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>
39 #include <com/sun/star/document/XDocumentProperties.hpp>
42 using namespace ::com::sun::star
;
45 static CharSet
lcl_GetDefaultTextEncodingForRTF()
48 OUString
aLangString( Application::GetSettings().GetLanguageTag().getLanguage());
50 if ( aLangString
== "ru" || aLangString
== "uk" )
51 return RTL_TEXTENCODING_MS_1251
;
52 if ( aLangString
== "tr" )
53 return RTL_TEXTENCODING_MS_1254
;
55 return RTL_TEXTENCODING_MS_1252
;
58 // -------------- Methods --------------------
60 SvxRTFParser::SvxRTFParser( SfxItemPool
& rPool
, SvStream
& rIn
,
61 uno::Reference
<document::XDocumentProperties
> i_xDocProps
,
63 : SvRTFParser( rIn
, 5 ),
67 m_xDocProps( i_xDocProps
),
71 bNewDoc
= bReadNewDoc
;
73 bChkStyleAttr
= bCalcValue
= bReadDocInfo
= bIsInReadStyleTab
= sal_False
;
74 bIsLeftToRightDef
= sal_True
;
77 RTFPlainAttrMapIds
aTmp( rPool
);
78 aPlainMap
.insert( aPlainMap
.begin(), (sal_uInt16
*)&aTmp
,
79 (sal_uInt16
*)&aTmp
+ (sizeof( RTFPlainAttrMapIds
) / sizeof(sal_uInt16
)) );
82 RTFPardAttrMapIds
aTmp( rPool
);
83 aPardMap
.insert( aPardMap
.begin(), (sal_uInt16
*)&aTmp
,
84 (sal_uInt16
*)&aTmp
+ (sizeof( RTFPardAttrMapIds
) / sizeof(sal_uInt16
)) );
87 pDfltColor
= new Color
;
90 void SvxRTFParser::EnterEnvironment()
94 void SvxRTFParser::LeaveEnvironment()
98 void SvxRTFParser::ResetPard()
102 SvxRTFParser::~SvxRTFParser()
104 if( !aColorTbl
.empty() )
106 if( !aAttrStack
.empty() )
116 void SvxRTFParser::SetInsPos( const SvxPosition
& rNew
)
120 pInsPos
= rNew
.Clone();
123 SvParserState
SvxRTFParser::CallParser()
125 DBG_ASSERT( pInsPos
, "no insertion position");
130 if( !aColorTbl
.empty() )
132 if( !aFontTbl
.empty() )
134 if( !aStyleTbl
.empty() )
136 if( !aAttrStack
.empty() )
139 bIsSetDfltTab
= sal_False
;
140 bNewGroup
= sal_False
;
145 // generate the correct WhichId table from the set WhichIds.
148 return SvRTFParser::CallParser();
151 void SvxRTFParser::Continue( int nToken
)
153 SvRTFParser::Continue( nToken
);
155 if( SVPAR_PENDING
!= GetStatus() )
158 //Regardless of what "color 0" is, word defaults to auto as the default colour.
164 // is called for each token that is recognized in CallParser
165 void SvxRTFParser::NextToken( int nToken
)
170 case RTF_COLORTBL
: ReadColorTable(); break;
171 case RTF_FONTTBL
: ReadFontTable(); break;
172 case RTF_STYLESHEET
: ReadStyleTable(); break;
177 if( !aFontTbl
.empty() )
178 // Can immediately be set
179 SetDefault( nToken
, nTokenValue
);
181 // is set after reading the font table
182 nDfltFont
= int(nTokenValue
);
189 SetDefault( nToken
, nTokenValue
);
193 case RTF_PICT
: ReadBitmapData(); break;
195 case RTF_LINE
: cCh
= '\n'; goto INSINGLECHAR
;
196 case RTF_TAB
: cCh
= '\t'; goto INSINGLECHAR
;
197 case RTF_SUBENTRYINDEX
: cCh
= ':'; goto INSINGLECHAR
;
199 case RTF_EMDASH
: cCh
= 0x2014; goto INSINGLECHAR
;
200 case RTF_ENDASH
: cCh
= 0x2013; goto INSINGLECHAR
;
201 case RTF_BULLET
: cCh
= 0x2022; goto INSINGLECHAR
;
202 case RTF_LQUOTE
: cCh
= 0x2018; goto INSINGLECHAR
;
203 case RTF_RQUOTE
: cCh
= 0x2019; goto INSINGLECHAR
;
204 case RTF_LDBLQUOTE
: cCh
= 0x201C; goto INSINGLECHAR
;
205 case RTF_RDBLQUOTE
: cCh
= 0x201D; goto INSINGLECHAR
;
207 aToken
= OUString(cCh
);
208 // no Break, aToken is set as Text
212 // all collected Attributes are set
213 for( sal_uInt16 n
= aAttrSetList
.size(); n
; )
215 SvxRTFItemStackType
* pStkSet
= &aAttrSetList
[--n
];
216 SetAttrSet( *pStkSet
);
217 aAttrSetList
.pop_back();
227 if (bNewGroup
) // Nesting!
233 if( !bNewGroup
) // Empty Group ??
239 if (bReadDocInfo
&& bNewDoc
&& m_xDocProps
.is())
245 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
246 // First overwrite all (all have to be in one group!!)
247 // Could also appear in the RTF-filewithout the IGNORE-Flag; all Groups
248 // with the IGNORE-Flag are overwritten in the default branch.
250 case RTF_SWG_PRTDATA
:
262 // RTF_SHPRSLT disabled for #i19718#
265 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
270 if( RTF_IGNOREFLAG
!= GetStackPtr( -1 )->nTokenId
)
272 nToken
= SkipToken( -1 );
273 if( '{' == GetStackPtr( -1 )->nTokenId
)
274 nToken
= SkipToken( -1 );
276 ReadAttr( nToken
, &GetAttrSet() );
280 switch( nToken
& ~(0xff | RTF_SWGDEFS
) )
282 case RTF_PARFMT
: // hier gibts keine Swg-Defines
283 ReadAttr( nToken
, &GetAttrSet() );
290 if( RTF_SWGDEFS
& nToken
)
292 if( RTF_IGNOREFLAG
!= GetStackPtr( -1 )->nTokenId
)
294 nToken
= SkipToken( -1 );
295 if( '{' == GetStackPtr( -1 )->nTokenId
)
297 nToken
= SkipToken( -1 );
300 ReadAttr( nToken
, &GetAttrSet() );
304 if( /*( '{' == GetStackPtr( -1 )->nTokenId ) ||*/
305 ( RTF_IGNOREFLAG
== GetStackPtr( -1 )->nTokenId
&&
306 '{' == GetStackPtr( -2 )->nTokenId
) )
315 void SvxRTFParser::ReadStyleTable()
317 int nToken
, bSaveChkStyleAttr
= bChkStyleAttr
;
318 sal_uInt16 nStyleNo
= 0;
319 int _nOpenBrakets
= 1; // the first was already detected earlier!!
320 SvxRTFStyleType
* pStyle
= new SvxRTFStyleType( *pAttrPool
, &aWhichMap
[0] );
321 pStyle
->aAttrSet
.Put( GetRTFDefaults() );
323 bIsInReadStyleTab
= sal_True
;
324 bChkStyleAttr
= sal_False
; // Do not check Attribute against the Styles
326 while( _nOpenBrakets
&& IsParserWorking() )
328 switch( nToken
= GetNextToken() )
330 case '}': if( --_nOpenBrakets
&& IsParserWorking() )
331 // Style has been completely read,
332 // so this is still a stable status
333 SaveState( RTF_STYLESHEET
);
337 if( RTF_IGNOREFLAG
!= GetNextToken() )
338 nToken
= SkipToken( -1 );
339 else if( RTF_UNKNOWNCONTROL
!= ( nToken
= GetNextToken() ) &&
341 nToken
= SkipToken( -2 );
344 // filter out at once
346 nToken
= GetNextToken();
348 eState
= SVPAR_ERROR
;
355 case RTF_SBASEDON
: pStyle
->nBasedOn
= sal_uInt16(nTokenValue
); pStyle
->bBasedOnIsSet
=sal_True
; break;
356 case RTF_SNEXT
: pStyle
->nNext
= sal_uInt16(nTokenValue
); break;
357 case RTF_OUTLINELEVEL
:
358 case RTF_SOUTLVL
: pStyle
->nOutlineNo
= sal_uInt8(nTokenValue
); break;
359 case RTF_S
: nStyleNo
= (short)nTokenValue
; break;
360 case RTF_CS
: nStyleNo
= (short)nTokenValue
;
361 pStyle
->bIsCharFmt
= sal_True
;
366 pStyle
->sName
= DelCharAtEnd( aToken
, ';' );
368 if( !aStyleTbl
.empty() )
370 aStyleTbl
.erase(nStyleNo
);
372 // All data from the font is available, so off to the table
373 aStyleTbl
.insert( nStyleNo
, pStyle
);
374 pStyle
= new SvxRTFStyleType( *pAttrPool
, &aWhichMap
[0] );
375 pStyle
->aAttrSet
.Put( GetRTFDefaults() );
380 switch( nToken
& ~(0xff | RTF_SWGDEFS
) )
382 case RTF_PARFMT
: // hier gibts keine Swg-Defines
383 ReadAttr( nToken
, &pStyle
->aAttrSet
);
390 if( RTF_SWGDEFS
& nToken
)
392 if( RTF_IGNOREFLAG
!= GetStackPtr( -1 )->nTokenId
)
394 nToken
= SkipToken( -1 );
395 if( '{' == GetStackPtr( -1 )->nTokenId
)
397 nToken
= SkipToken( -1 );
400 ReadAttr( nToken
, &pStyle
->aAttrSet
);
406 delete pStyle
; // Delete the Last Style
407 SkipToken( -1 ); // the closing brace is evaluated "above"
409 // Flag back to old state
410 bChkStyleAttr
= bSaveChkStyleAttr
;
411 bIsInReadStyleTab
= sal_False
;
414 void SvxRTFParser::ReadColorTable()
417 sal_uInt8 nRed
= 0xff, nGreen
= 0xff, nBlue
= 0xff;
419 while( '}' != ( nToken
= GetNextToken() ) && IsParserWorking() )
423 case RTF_RED
: nRed
= sal_uInt8(nTokenValue
); break;
424 case RTF_GREEN
: nGreen
= sal_uInt8(nTokenValue
); break;
425 case RTF_BLUE
: nBlue
= sal_uInt8(nTokenValue
); break;
428 if( 1 == aToken
.Len()
429 ? aToken
.GetChar( 0 ) != ';'
430 : STRING_NOTFOUND
== aToken
.Search( ';' ) )
431 break; // At least the ';' must be found
436 if( IsParserWorking() )
438 // one color is finished, fill in the table
439 // try to map the values to SV internal names
440 ColorPtr pColor
= new Color( nRed
, nGreen
, nBlue
);
441 if( aColorTbl
.empty() &&
442 sal_uInt8(-1) == nRed
&& sal_uInt8(-1) == nGreen
&& sal_uInt8(-1) == nBlue
)
443 pColor
->SetColor( COL_AUTO
);
444 aColorTbl
.push_back( pColor
);
445 nRed
= 0, nGreen
= 0, nBlue
= 0;
447 // Color has been completely read,
448 // so this is still a stable status
449 SaveState( RTF_COLORTBL
);
454 SkipToken( -1 ); // the closing brace is evaluated "above"
457 void SvxRTFParser::ReadFontTable()
460 int _nOpenBrakets
= 1; // the first was already detected earlier!!
461 Font
* pFont
= new Font();
462 short nFontNo(0), nInsFontNo (0);
463 String sAltNm
, sFntNm
;
464 sal_Bool bIsAltFntNm
= sal_False
, bCheckNewFont
;
466 CharSet nSystemChar
= lcl_GetDefaultTextEncodingForRTF();
467 pFont
->SetCharSet( nSystemChar
);
468 SetEncoding( nSystemChar
);
470 while( _nOpenBrakets
&& IsParserWorking() )
472 bCheckNewFont
= sal_False
;
473 switch( ( nToken
= GetNextToken() ))
476 bIsAltFntNm
= sal_False
;
477 // Style has been completely read,
478 // so this is still a stable status
479 if( --_nOpenBrakets
<= 1 && IsParserWorking() )
480 SaveState( RTF_FONTTBL
);
481 bCheckNewFont
= sal_True
;
482 nInsFontNo
= nFontNo
;
485 if( RTF_IGNOREFLAG
!= GetNextToken() )
486 nToken
= SkipToken( -1 );
487 // immediately skip unknown and all known but non-evaluated
489 else if( RTF_UNKNOWNCONTROL
!= ( nToken
= GetNextToken() ) &&
490 RTF_PANOSE
!= nToken
&& RTF_FNAME
!= nToken
&&
491 RTF_FONTEMB
!= nToken
&& RTF_FONTFILE
!= nToken
)
492 nToken
= SkipToken( -2 );
495 // filter out at once
497 nToken
= GetNextToken();
499 eState
= SVPAR_ERROR
;
505 pFont
->SetFamily( FAMILY_ROMAN
);
508 pFont
->SetFamily( FAMILY_SWISS
);
511 pFont
->SetFamily( FAMILY_MODERN
);
514 pFont
->SetFamily( FAMILY_SCRIPT
);
517 pFont
->SetFamily( FAMILY_DECORATIVE
);
519 // for technical/symbolic font of the CharSet is changed!
521 pFont
->SetCharSet( RTL_TEXTENCODING_SYMBOL
);
522 // deliberate fall through
524 pFont
->SetFamily( FAMILY_DONTKNOW
);
527 if (-1 != nTokenValue
)
529 CharSet nCharSet
= rtl_getTextEncodingFromWindowsCharset(
530 (sal_uInt8
)nTokenValue
);
531 pFont
->SetCharSet(nCharSet
);
532 //When we're in a font, the fontname is in the font
533 //charset, except for symbol fonts I believe
534 if (nCharSet
== RTL_TEXTENCODING_SYMBOL
)
535 nCharSet
= RTL_TEXTENCODING_DONTKNOW
;
536 SetEncoding(nCharSet
);
540 switch( nTokenValue
)
543 pFont
->SetPitch( PITCH_FIXED
);
546 pFont
->SetPitch( PITCH_VARIABLE
);
551 bCheckNewFont
= sal_True
;
552 nInsFontNo
= nFontNo
;
553 nFontNo
= (short)nTokenValue
;
556 bIsAltFntNm
= sal_True
;
559 DelCharAtEnd( aToken
, ';' );
570 if( bCheckNewFont
&& 1 >= _nOpenBrakets
&& sFntNm
.Len() ) // one font is ready
572 // All data from the font is available, so off to the table
574 (sFntNm
+= ';' ) += sAltNm
;
576 pFont
->SetName( sFntNm
);
577 aFontTbl
.insert( nInsFontNo
, pFont
);
579 pFont
->SetCharSet( nSystemChar
);
584 // the last one we have to delete manually
586 SkipToken( -1 ); // the closing brace is evaluated "above"
588 // set the default font in the Document
589 if( bNewDoc
&& IsParserWorking() )
590 SetDefault( RTF_DEFF
, nDfltFont
);
593 void SvxRTFParser::ReadBitmapData()
595 SvRTFParser::ReadBitmapData();
598 void SvxRTFParser::ReadOLEData()
600 SvRTFParser::ReadOLEData();
603 String
& SvxRTFParser::GetTextToEndGroup( String
& rStr
)
606 int _nOpenBrakets
= 1, nToken
; // the first was already detected earlier!!
608 while( _nOpenBrakets
&& IsParserWorking() )
610 switch( nToken
= GetNextToken() )
612 case '}': --_nOpenBrakets
; break;
615 if( RTF_IGNOREFLAG
!= GetNextToken() )
616 nToken
= SkipToken( -1 );
617 else if( RTF_UNKNOWNCONTROL
!= GetNextToken() )
618 nToken
= SkipToken( -2 );
621 // filter out at once
623 nToken
= GetNextToken();
625 eState
= SVPAR_ERROR
;
637 SkipToken( -1 ); // the closing brace is evaluated "above"
641 util::DateTime
SvxRTFParser::GetDateTimeStamp( )
644 sal_Bool bWeiter
= sal_True
;
646 while( bWeiter
&& IsParserWorking() )
648 int nToken
= GetNextToken();
651 case RTF_YR
: aDT
.Year
= (sal_uInt16
)nTokenValue
; break;
652 case RTF_MO
: aDT
.Month
= (sal_uInt16
)nTokenValue
; break;
653 case RTF_DY
: aDT
.Day
= (sal_uInt16
)nTokenValue
; break;
654 case RTF_HR
: aDT
.Hours
= (sal_uInt16
)nTokenValue
; break;
655 case RTF_MIN
: aDT
.Minutes
= (sal_uInt16
)nTokenValue
; break;
660 SkipToken( -1 ); // the closing brace is evaluated "above"
664 void SvxRTFParser::ReadInfo( const sal_Char
* pChkForVerNo
)
666 int _nOpenBrakets
= 1, nToken
; // the first was already detected earlier!!
667 DBG_ASSERT(m_xDocProps
.is(),
668 "SvxRTFParser::ReadInfo: no DocumentProperties");
669 String sStr
, sComment
;
672 while( _nOpenBrakets
&& IsParserWorking() )
674 switch( nToken
= GetNextToken() )
676 case '}': --_nOpenBrakets
; break;
679 if( RTF_IGNOREFLAG
!= GetNextToken() )
680 nToken
= SkipToken( -1 );
681 else if( RTF_UNKNOWNCONTROL
!= GetNextToken() )
682 nToken
= SkipToken( -2 );
685 // filter out at once
687 nToken
= GetNextToken();
689 eState
= SVPAR_ERROR
;
697 m_xDocProps
->setTitle( GetTextToEndGroup( sStr
) );
700 m_xDocProps
->setSubject( GetTextToEndGroup( sStr
) );
703 m_xDocProps
->setAuthor( GetTextToEndGroup( sStr
) );
706 m_xDocProps
->setModifiedBy( GetTextToEndGroup( sStr
) );
710 OUString sTemp
= GetTextToEndGroup( sStr
);
711 m_xDocProps
->setKeywords(
712 ::comphelper::string::convertCommaSeparated(sTemp
) );
716 m_xDocProps
->setDescription( GetTextToEndGroup( sStr
) );
720 sBaseURL
= GetTextToEndGroup( sStr
) ;
724 m_xDocProps
->setCreationDate( GetDateTimeStamp() );
728 m_xDocProps
->setModificationDate( GetDateTimeStamp() );
732 m_xDocProps
->setPrintDate( GetDateTimeStamp() );
736 GetTextToEndGroup( sComment
);
744 nVersNo
= nTokenValue
;
761 COMPARE_EQUAL
== sComment
.CompareToAscii( pChkForVerNo
))
762 nVersionNo
= nVersNo
;
764 SkipToken( -1 ); // the closing brace is evaluated "above"
768 void SvxRTFParser::ClearColorTbl()
770 while ( !aColorTbl
.empty() )
772 delete aColorTbl
.back();
773 aColorTbl
.pop_back();
777 void SvxRTFParser::ClearFontTbl()
782 void SvxRTFParser::ClearStyleTbl()
787 void SvxRTFParser::ClearAttrStack()
789 SvxRTFItemStackType
* pTmp
;
790 for( size_t nCnt
= aAttrStack
.size(); nCnt
; --nCnt
)
792 pTmp
= aAttrStack
.back();
793 aAttrStack
.pop_back();
798 String
& SvxRTFParser::DelCharAtEnd( String
& rStr
, const sal_Unicode cDel
)
800 if( rStr
.Len() && ' ' == rStr
.GetChar( 0 ))
801 rStr
= comphelper::string::stripStart(rStr
, ' ');
802 if( rStr
.Len() && ' ' == rStr
.GetChar( rStr
.Len()-1 ))
803 rStr
= comphelper::string::stripEnd(rStr
, ' ');
804 if( rStr
.Len() && cDel
== rStr
.GetChar( rStr
.Len()-1 ))
805 rStr
.Erase( rStr
.Len()-1 );
810 const Font
& SvxRTFParser::GetFont( sal_uInt16 nId
)
812 SvxRTFFontTbl::const_iterator it
= aFontTbl
.find( nId
);
814 if( it
== aFontTbl
.end() )
816 const SvxFontItem
& rDfltFont
= (const SvxFontItem
&)
817 pAttrPool
->GetDefaultItem(
818 ((RTFPlainAttrMapIds
*)&aPlainMap
[0])->nFont
);
819 pDfltFont
->SetName( rDfltFont
.GetStyleName() );
820 pDfltFont
->SetFamily( rDfltFont
.GetFamily() );
828 SvxRTFItemStackType
* SvxRTFParser::_GetAttrSet( int bCopyAttr
)
830 SvxRTFItemStackType
* pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
831 SvxRTFItemStackType
* pNew
;
833 pNew
= new SvxRTFItemStackType( *pAkt
, *pInsPos
, bCopyAttr
);
835 pNew
= new SvxRTFItemStackType( *pAttrPool
, &aWhichMap
[0],
837 pNew
->SetRTFDefaults( GetRTFDefaults() );
839 aAttrStack
.push_back( pNew
);
840 bNewGroup
= sal_False
;
845 void SvxRTFParser::_ClearStyleAttr( SvxRTFItemStackType
& rStkType
)
847 // check attributes to the attributes of the stylesheet or to
848 // the default attrs of the document
849 SfxItemSet
&rSet
= rStkType
.GetAttrSet();
850 const SfxItemPool
& rPool
= *rSet
.GetPool();
851 const SfxPoolItem
* pItem
;
852 SfxWhichIter
aIter( rSet
);
854 if( !IsChkStyleAttr() ||
855 !rStkType
.GetAttrSet().Count() ||
856 aStyleTbl
.count( rStkType
.nStyleNo
) == 0 )
858 for( sal_uInt16 nWhich
= aIter
.GetCurWhich(); nWhich
; nWhich
= aIter
.NextWhich() )
860 if( SFX_WHICH_MAX
> nWhich
&&
861 SFX_ITEM_SET
== rSet
.GetItemState( nWhich
, sal_False
, &pItem
) &&
862 rPool
.GetDefaultItem( nWhich
) == *pItem
)
863 rSet
.ClearItem( nWhich
); // delete
868 // Delete all Attributes, which are already defined in the Style,
869 // from the current AttrSet.
870 SvxRTFStyleType
* pStyle
= aStyleTbl
.find( rStkType
.nStyleNo
)->second
;
871 SfxItemSet
&rStyleSet
= pStyle
->aAttrSet
;
872 const SfxPoolItem
* pSItem
;
873 for( sal_uInt16 nWhich
= aIter
.GetCurWhich(); nWhich
; nWhich
= aIter
.NextWhich() )
875 if( SFX_ITEM_SET
== rStyleSet
.GetItemState( nWhich
, sal_True
, &pSItem
))
877 if( SFX_ITEM_SET
== rSet
.GetItemState( nWhich
, sal_False
, &pItem
)
878 && *pItem
== *pSItem
)
879 rSet
.ClearItem( nWhich
); // delete
881 else if( SFX_WHICH_MAX
> nWhich
&&
882 SFX_ITEM_SET
== rSet
.GetItemState( nWhich
, sal_False
, &pItem
) &&
883 rPool
.GetDefaultItem( nWhich
) == *pItem
)
884 rSet
.ClearItem( nWhich
); // delete
889 void SvxRTFParser::AttrGroupEnd() // process the current, delete from Stack
891 if( !aAttrStack
.empty() )
893 SvxRTFItemStackType
*pOld
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
894 aAttrStack
.pop_back();
895 SvxRTFItemStackType
*pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
897 do { // middle check loop
898 sal_Int32 nOldSttNdIdx
= pOld
->pSttNd
->GetIdx();
899 if( !pOld
->pChildList
&&
900 ((!pOld
->aAttrSet
.Count() && !pOld
->nStyleNo
) ||
901 (nOldSttNdIdx
== pInsPos
->GetNodeIdx() &&
902 pOld
->nSttCnt
== pInsPos
->GetCntIdx() )))
903 break; // no attributes or Area
905 // set only the attributes that are different from the parent
906 if( pAkt
&& pOld
->aAttrSet
.Count() )
908 SfxItemIter
aIter( pOld
->aAttrSet
);
909 const SfxPoolItem
* pItem
= aIter
.GetCurItem(), *pGet
;
912 if( SFX_ITEM_SET
== pAkt
->aAttrSet
.GetItemState(
913 pItem
->Which(), sal_False
, &pGet
) &&
915 pOld
->aAttrSet
.ClearItem( pItem
->Which() );
917 if( aIter
.IsAtEnd() )
919 pItem
= aIter
.NextItem();
922 if( !pOld
->aAttrSet
.Count() && !pOld
->pChildList
&&
927 // Set all attributes which have been defined from start until here
928 int bCrsrBack
= !pInsPos
->GetCntIdx();
931 // at the beginning of a paragraph? Move back one position
932 sal_Int32 nNd
= pInsPos
->GetNodeIdx();
933 MovePos( sal_False
);
934 // if can not move backward then later dont move forward !
935 bCrsrBack
= nNd
!= pInsPos
->GetNodeIdx();
938 if( ( pOld
->pSttNd
->GetIdx() < pInsPos
->GetNodeIdx() ||
939 ( pOld
->pSttNd
->GetIdx() == pInsPos
->GetNodeIdx() &&
940 pOld
->nSttCnt
<= pInsPos
->GetCntIdx() ))
945 // all pard attributes are only valid until the previous
947 if( nOldSttNdIdx
== pInsPos
->GetNodeIdx() )
952 // Now it gets complicated:
953 // - all character attributes sre keep the area
954 // - all paragraph attributes to get the area
955 // up to the previous paragraph
956 SvxRTFItemStackType
* pNew
= new SvxRTFItemStackType(
957 *pOld
, *pInsPos
, sal_True
);
958 pNew
->aAttrSet
.SetParent( pOld
->aAttrSet
.GetParent() );
960 // Delete all paragraph attributes from pNew
961 for( sal_uInt16 n
= 0; n
< aPardMap
.size() &&
962 pNew
->aAttrSet
.Count(); ++n
)
964 pNew
->aAttrSet
.ClearItem( aPardMap
[n
] );
965 pNew
->SetRTFDefaults( GetRTFDefaults() );
968 if( pNew
->aAttrSet
.Count() == pOld
->aAttrSet
.Count() )
974 // Now span the real area of pNew from old
975 SetEndPrevPara( pOld
->pEndNd
, pOld
->nEndCnt
);
978 if( IsChkStyleAttr() )
980 _ClearStyleAttr( *pOld
);
981 _ClearStyleAttr( *pNew
); //#i10381#, methinks.
991 // Last off the stack, thus cache it until the next text was
992 // read. (Span no attributes!)
994 aAttrSetList
.push_back( pOld
);
995 aAttrSetList
.push_back( pNew
);
997 pOld
= 0; // Do not delete pOld
1003 pOld
->pEndNd
= pInsPos
->MakeNodeIdx();
1004 pOld
->nEndCnt
= pInsPos
->GetCntIdx();
1008 If the parent (pAkt) sets something e.g. , and the child (pOld)
1009 unsets it and the style both are based on has it unset then
1010 clearing the pOld by looking at the style is clearly a disaster
1011 as the text ends up with pAkts bold and not pOlds no bold, this
1012 should be rethought out. For the moment its safest to just do
1013 the clean if we have no parent, all we suffer is too many
1014 redundant properties.
1016 if (IsChkStyleAttr() && !pAkt
)
1017 _ClearStyleAttr( *pOld
);
1022 // split up and create new entry, because it make no sense
1023 // to create a "so long" depend list. Bug 95010
1024 if( bCrsrBack
&& 50 < pAkt
->pChildList
->size() )
1026 // at the beginning of a paragraph? Move back one position
1027 MovePos( sal_True
);
1028 bCrsrBack
= sal_False
;
1030 // Open a new Group.
1031 SvxRTFItemStackType
* pNew
= new SvxRTFItemStackType(
1032 *pAkt
, *pInsPos
, sal_True
);
1033 pNew
->SetRTFDefaults( GetRTFDefaults() );
1035 // Set all until here valid Attributes
1037 pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back(); // can be changed after AttrGroupEnd!
1038 pNew
->aAttrSet
.SetParent( pAkt
? &pAkt
->aAttrSet
: 0 );
1039 aAttrStack
.push_back( pNew
);
1044 // Last off the stack, thus cache it until the next text was
1045 // read. (Span no attributes!)
1046 aAttrSetList
.push_back( pOld
);
1052 // at the beginning of a paragraph? Move back one position
1053 MovePos( sal_True
);
1060 bNewGroup
= sal_False
;
1064 void SvxRTFParser::SetAllAttrOfStk() // end all Attr. and set it into doc
1066 // repeat until all attributes will be taken from stack
1067 while( !aAttrStack
.empty() )
1070 for( sal_uInt16 n
= aAttrSetList
.size(); n
; )
1072 SvxRTFItemStackType
* pStkSet
= &aAttrSetList
[--n
];
1073 SetAttrSet( *pStkSet
);
1074 aAttrSetList
.pop_back();
1078 // sets all the attributes that are different from the current
1079 void SvxRTFParser::SetAttrSet( SvxRTFItemStackType
&rSet
)
1081 // Was DefTab never read? then set to default
1082 if( !bIsSetDfltTab
)
1083 SetDefault( RTF_DEFTAB
, 720 );
1085 if( rSet
.pChildList
)
1086 rSet
.Compress( *this );
1087 if( rSet
.aAttrSet
.Count() || rSet
.nStyleNo
)
1088 SetAttrInDoc( rSet
);
1090 // then process all the children
1091 if( rSet
.pChildList
)
1092 for( sal_uInt16 n
= 0; n
< rSet
.pChildList
->size(); ++n
)
1093 SetAttrSet( (*rSet
.pChildList
)[ n
] );
1096 // Has no Text been inserted yet? (SttPos from the top Stack entry!)
1097 int SvxRTFParser::IsAttrSttPos()
1099 SvxRTFItemStackType
* pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
1100 return !pAkt
|| (pAkt
->pSttNd
->GetIdx() == pInsPos
->GetNodeIdx() &&
1101 pAkt
->nSttCnt
== pInsPos
->GetCntIdx());
1105 void SvxRTFParser::SetAttrInDoc( SvxRTFItemStackType
& )
1109 void SvxRTFParser::BuildWhichTbl()
1112 aWhichMap
.push_back( 0 );
1114 // Building a Which-Map 'rWhichMap' from an Array of
1115 // 'pWhichIds' frm Which-Ids. It has the long 'nWhichIds'.
1116 // The Which-Map is not going to be deleted.
1117 SvParser::BuildWhichTbl( aWhichMap
, (sal_uInt16
*)&aPardMap
[0], aPardMap
.size() );
1118 SvParser::BuildWhichTbl( aWhichMap
, (sal_uInt16
*)&aPlainMap
[0], aPlainMap
.size() );
1121 const SfxItemSet
& SvxRTFParser::GetRTFDefaults()
1125 pRTFDefaults
= new SfxItemSet( *pAttrPool
, &aWhichMap
[0] );
1127 if( 0 != ( nId
= ((RTFPardAttrMapIds
*)&aPardMap
[0])->nScriptSpace
))
1129 SvxScriptSpaceItem
aItem( sal_False
, nId
);
1131 pAttrPool
->SetPoolDefaultItem( aItem
);
1133 pRTFDefaults
->Put( aItem
);
1136 return *pRTFDefaults
;
1140 SvxRTFStyleType::SvxRTFStyleType( SfxItemPool
& rPool
, const sal_uInt16
* pWhichRange
)
1141 : aAttrSet( rPool
, pWhichRange
)
1143 nOutlineNo
= sal_uInt8(-1); // not set
1145 bBasedOnIsSet
= sal_False
; //$flr #117411#
1147 bIsCharFmt
= sal_False
;
1151 SvxRTFItemStackType::SvxRTFItemStackType(
1152 SfxItemPool
& rPool
, const sal_uInt16
* pWhichRange
,
1153 const SvxPosition
& rPos
)
1154 : aAttrSet( rPool
, pWhichRange
),
1158 pSttNd
= rPos
.MakeNodeIdx();
1159 nSttCnt
= rPos
.GetCntIdx();
1164 SvxRTFItemStackType::SvxRTFItemStackType(
1165 const SvxRTFItemStackType
& rCpy
,
1166 const SvxPosition
& rPos
,
1168 : aAttrSet( *rCpy
.aAttrSet
.GetPool(), rCpy
.aAttrSet
.GetRanges() ),
1170 nStyleNo( rCpy
.nStyleNo
)
1172 pSttNd
= rPos
.MakeNodeIdx();
1173 nSttCnt
= rPos
.GetCntIdx();
1177 aAttrSet
.SetParent( &rCpy
.aAttrSet
);
1179 aAttrSet
.Put( rCpy
.aAttrSet
);
1182 SvxRTFItemStackType::~SvxRTFItemStackType()
1186 if( pSttNd
!= pEndNd
)
1191 void SvxRTFItemStackType::Add( SvxRTFItemStackType
* pIns
)
1194 pChildList
= new SvxRTFItemStackList();
1195 pChildList
->push_back( pIns
);
1198 void SvxRTFItemStackType::SetStartPos( const SvxPosition
& rPos
)
1200 if (pSttNd
!= pEndNd
)
1203 pSttNd
= rPos
.MakeNodeIdx();
1205 nSttCnt
= rPos
.GetCntIdx();
1208 void SvxRTFItemStackType::MoveFullNode(const SvxNodeIdx
&rOldNode
,
1209 const SvxNodeIdx
&rNewNode
)
1211 bool bSameEndAsStart
= (pSttNd
== pEndNd
) ? true : false;
1213 if (GetSttNodeIdx() == rOldNode
.GetIdx())
1216 pSttNd
= rNewNode
.Clone();
1217 if (bSameEndAsStart
)
1221 if (!bSameEndAsStart
&& GetEndNodeIdx() == rOldNode
.GetIdx())
1224 pEndNd
= rNewNode
.Clone();
1227 //And the same for all the children
1228 sal_Int32 nCount
= pChildList
? pChildList
->size() : 0;
1229 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
1231 SvxRTFItemStackType
* pStk
= &(*pChildList
)[i
];
1232 pStk
->MoveFullNode(rOldNode
, rNewNode
);
1236 bool SvxRTFParser::UncompressableStackEntry(const SvxRTFItemStackType
&) const
1241 void SvxRTFItemStackType::Compress( const SvxRTFParser
& rParser
)
1243 ENSURE_OR_RETURN_VOID(pChildList
, "Compress: no ChildList" );
1244 ENSURE_OR_RETURN_VOID(!pChildList
->empty(), "Compress: ChildList empty");
1247 SvxRTFItemStackType
* pTmp
= &(*pChildList
)[0];
1249 if( !pTmp
->aAttrSet
.Count() ||
1250 pSttNd
->GetIdx() != pTmp
->pSttNd
->GetIdx() ||
1251 nSttCnt
!= pTmp
->nSttCnt
)
1254 SvxNodeIdx
* pLastNd
= pTmp
->pEndNd
;
1255 xub_StrLen nLastCnt
= pTmp
->nEndCnt
;
1257 SfxItemSet
aMrgSet( pTmp
->aAttrSet
);
1258 for( n
= 1; n
< pChildList
->size(); ++n
)
1260 pTmp
= &(*pChildList
)[n
];
1261 if( pTmp
->pChildList
)
1262 pTmp
->Compress( rParser
);
1265 ? (pLastNd
->GetIdx()+1 != pTmp
->pSttNd
->GetIdx() ||
1266 !rParser
.IsEndPara( pLastNd
, nLastCnt
) )
1267 : ( pTmp
->nSttCnt
!= nLastCnt
||
1268 pLastNd
->GetIdx() != pTmp
->pSttNd
->GetIdx() ))
1270 while( ++n
< pChildList
->size() )
1271 if( (pTmp
= &(*pChildList
)[n
])->pChildList
)
1272 pTmp
->Compress( rParser
);
1276 if (rParser
.UncompressableStackEntry(*pTmp
))
1281 // Search for all which are set over the whole area
1282 SfxItemIter
aIter( aMrgSet
);
1283 const SfxPoolItem
* pItem
;
1285 sal_uInt16 nWhich
= aIter
.GetCurItem()->Which();
1286 if( SFX_ITEM_SET
!= pTmp
->aAttrSet
.GetItemState( nWhich
,
1287 sal_False
, &pItem
) || *pItem
!= *aIter
.GetCurItem() )
1288 aMrgSet
.ClearItem( nWhich
);
1290 if( aIter
.IsAtEnd() )
1295 if( !aMrgSet
.Count() )
1299 pLastNd
= pTmp
->pEndNd
;
1300 nLastCnt
= pTmp
->nEndCnt
;
1303 if( pEndNd
->GetIdx() != pLastNd
->GetIdx() || nEndCnt
!= nLastCnt
)
1307 aAttrSet
.Put( aMrgSet
);
1309 for( n
= 0; n
< pChildList
->size(); ++n
)
1311 pTmp
= &(*pChildList
)[n
];
1312 pTmp
->aAttrSet
.Differentiate( aMrgSet
);
1314 if( !pTmp
->pChildList
&& !pTmp
->aAttrSet
.Count() && !pTmp
->nStyleNo
)
1316 pChildList
->erase( pChildList
->begin() + n
);
1321 if( pChildList
->empty() )
1327 void SvxRTFItemStackType::SetRTFDefaults( const SfxItemSet
& rDefaults
)
1329 if( rDefaults
.Count() )
1331 SfxItemIter
aIter( rDefaults
);
1333 sal_uInt16 nWhich
= aIter
.GetCurItem()->Which();
1334 if( SFX_ITEM_SET
!= aAttrSet
.GetItemState( nWhich
, sal_False
))
1335 aAttrSet
.Put( *aIter
.GetCurItem() );
1337 if( aIter
.IsAtEnd() )
1345 RTFPlainAttrMapIds::RTFPlainAttrMapIds( const SfxItemPool
& rPool
)
1347 nCaseMap
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CASEMAP
, sal_False
);
1348 nBgColor
= rPool
.GetTrueWhich( SID_ATTR_BRUSH_CHAR
, sal_False
);
1349 nColor
= rPool
.GetTrueWhich( SID_ATTR_CHAR_COLOR
, sal_False
);
1350 nContour
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CONTOUR
, sal_False
);
1351 nCrossedOut
= rPool
.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT
, sal_False
);
1352 nEscapement
= rPool
.GetTrueWhich( SID_ATTR_CHAR_ESCAPEMENT
, sal_False
);
1353 nFont
= rPool
.GetTrueWhich( SID_ATTR_CHAR_FONT
, sal_False
);
1354 nFontHeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT
, sal_False
);
1355 nKering
= rPool
.GetTrueWhich( SID_ATTR_CHAR_KERNING
, sal_False
);
1356 nLanguage
= rPool
.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE
, sal_False
);
1357 nPosture
= rPool
.GetTrueWhich( SID_ATTR_CHAR_POSTURE
, sal_False
);
1358 nShadowed
= rPool
.GetTrueWhich( SID_ATTR_CHAR_SHADOWED
, sal_False
);
1359 nUnderline
= rPool
.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE
, sal_False
);
1360 nOverline
= rPool
.GetTrueWhich( SID_ATTR_CHAR_OVERLINE
, sal_False
);
1361 nWeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_WEIGHT
, sal_False
);
1362 nWordlineMode
= rPool
.GetTrueWhich( SID_ATTR_CHAR_WORDLINEMODE
, sal_False
);
1363 nAutoKerning
= rPool
.GetTrueWhich( SID_ATTR_CHAR_AUTOKERN
, sal_False
);
1365 nCJKFont
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT
, sal_False
);
1366 nCJKFontHeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT
, sal_False
);
1367 nCJKLanguage
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE
, sal_False
);
1368 nCJKPosture
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE
, sal_False
);
1369 nCJKWeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT
, sal_False
);
1370 nCTLFont
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT
, sal_False
);
1371 nCTLFontHeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT
, sal_False
);
1372 nCTLLanguage
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE
, sal_False
);
1373 nCTLPosture
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE
, sal_False
);
1374 nCTLWeight
= rPool
.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT
, sal_False
);
1375 nEmphasis
= rPool
.GetTrueWhich( SID_ATTR_CHAR_EMPHASISMARK
, sal_False
);
1376 nTwoLines
= rPool
.GetTrueWhich( SID_ATTR_CHAR_TWO_LINES
, sal_False
);
1377 nRuby
= 0; //rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_RUBY, sal_False );
1378 nCharScaleX
= rPool
.GetTrueWhich( SID_ATTR_CHAR_SCALEWIDTH
, sal_False
);
1379 nHorzVert
= rPool
.GetTrueWhich( SID_ATTR_CHAR_ROTATED
, sal_False
);
1380 nRelief
= rPool
.GetTrueWhich( SID_ATTR_CHAR_RELIEF
, sal_False
);
1381 nHidden
= rPool
.GetTrueWhich( SID_ATTR_CHAR_HIDDEN
, sal_False
);
1384 RTFPardAttrMapIds ::RTFPardAttrMapIds ( const SfxItemPool
& rPool
)
1386 nLinespacing
= rPool
.GetTrueWhich( SID_ATTR_PARA_LINESPACE
, sal_False
);
1387 nAdjust
= rPool
.GetTrueWhich( SID_ATTR_PARA_ADJUST
, sal_False
);
1388 nTabStop
= rPool
.GetTrueWhich( SID_ATTR_TABSTOP
, sal_False
);
1389 nHyphenzone
= rPool
.GetTrueWhich( SID_ATTR_PARA_HYPHENZONE
, sal_False
);
1390 nLRSpace
= rPool
.GetTrueWhich( SID_ATTR_LRSPACE
, sal_False
);
1391 nULSpace
= rPool
.GetTrueWhich( SID_ATTR_ULSPACE
, sal_False
);
1392 nBrush
= rPool
.GetTrueWhich( SID_ATTR_BRUSH
, sal_False
);
1393 nBox
= rPool
.GetTrueWhich( SID_ATTR_BORDER_OUTER
, sal_False
);
1394 nShadow
= rPool
.GetTrueWhich( SID_ATTR_BORDER_SHADOW
, sal_False
);
1395 nOutlineLvl
= rPool
.GetTrueWhich( SID_ATTR_PARA_OUTLLEVEL
, sal_False
);
1396 nSplit
= rPool
.GetTrueWhich( SID_ATTR_PARA_SPLIT
, sal_False
);
1397 nKeep
= rPool
.GetTrueWhich( SID_ATTR_PARA_KEEP
, sal_False
);
1398 nFontAlign
= rPool
.GetTrueWhich( SID_PARA_VERTALIGN
, sal_False
);
1399 nScriptSpace
= rPool
.GetTrueWhich( SID_ATTR_PARA_SCRIPTSPACE
, sal_False
);
1400 nHangPunct
= rPool
.GetTrueWhich( SID_ATTR_PARA_HANGPUNCTUATION
, sal_False
);
1401 nForbRule
= rPool
.GetTrueWhich( SID_ATTR_PARA_FORBIDDEN_RULES
, sal_False
);
1402 nDirection
= rPool
.GetTrueWhich( SID_ATTR_FRAMEDIRECTION
, sal_False
);
1405 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */