bump product version to 5.0.4.1
[LibreOffice.git] / editeng / source / rtf / svxrtf.cxx
blobec633c8c3fa380e0a6b49af317738e109f63b0e3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <ctype.h>
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;
55 else
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 )
65 , rStrm(rIn)
66 , aPlainMap(rPool)
67 , aPardMap(rPool)
68 , pInsPos( 0 )
69 , pAttrPool( &rPool )
70 , m_xDocProps( i_xDocProps )
71 , pRTFDefaults( 0 )
72 , nVersionNo( 0 )
73 , nDfltFont( 0)
74 , bNewDoc( bReadNewDoc )
75 , bNewGroup( false)
76 , bIsSetDfltTab( false)
77 , bChkStyleAttr( false )
78 , bCalcValue( 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() )
91 ClearColorTbl();
92 if( !aAttrStack.empty() )
93 ClearAttrStack();
95 delete pRTFDefaults;
97 delete pInsPos;
98 delete pDfltFont;
99 delete pDfltColor;
102 void SvxRTFParser::SetInsPos( const SvxPosition& rNew )
104 if( pInsPos )
105 delete pInsPos;
106 pInsPos = rNew.Clone();
109 SvParserState SvxRTFParser::CallParser()
111 DBG_ASSERT( pInsPos, "no insertion position");
113 if( !pInsPos )
114 return SVPAR_ERROR;
116 if( !aColorTbl.empty() )
117 ClearColorTbl();
118 if( !aFontTbl.empty() )
119 ClearFontTbl();
120 if( !aStyleTbl.empty() )
121 ClearStyleTbl();
122 if( !aAttrStack.empty() )
123 ClearAttrStack();
125 bIsSetDfltTab = false;
126 bNewGroup = false;
127 nDfltFont = 0;
129 sBaseURL.clear();
131 // generate the correct WhichId table from the set WhichIds.
132 BuildWhichTable();
134 return SvRTFParser::CallParser();
137 void SvxRTFParser::Continue( int nToken )
139 SvRTFParser::Continue( nToken );
141 if( SVPAR_PENDING != GetStatus() )
143 SetAllAttrOfStk();
144 //Regardless of what "color 0" is, word defaults to auto as the default colour.
145 //e.g. see #i7713#
150 // is called for each token that is recognized in CallParser
151 void SvxRTFParser::NextToken( int nToken )
153 sal_Unicode cCh;
154 switch( nToken )
156 case RTF_COLORTBL: ReadColorTable(); break;
157 case RTF_FONTTBL: ReadFontTable(); break;
158 case RTF_STYLESHEET: ReadStyleTable(); break;
160 case RTF_DEFF:
161 if( bNewDoc )
163 if( !aFontTbl.empty() )
164 // Can immediately be set
165 SetDefault( nToken, nTokenValue );
166 else
167 // is set after reading the font table
168 nDfltFont = int(nTokenValue);
170 break;
172 case RTF_DEFTAB:
173 case RTF_DEFLANG:
174 if( bNewDoc )
175 SetDefault( nToken, nTokenValue );
176 break;
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;
192 INSINGLECHAR:
193 aToken = OUString(cCh);
194 // no Break, aToken is set as Text
195 case RTF_TEXTTOKEN:
197 InsertText();
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();
206 break;
209 case RTF_PAR:
210 InsertPara();
211 break;
212 case '{':
213 if (bNewGroup) // Nesting!
214 _GetAttrSet();
215 bNewGroup = true;
216 break;
217 case '}':
218 if( !bNewGroup ) // Empty Group ??
219 AttrGroupEnd();
220 bNewGroup = false;
221 break;
222 case RTF_INFO:
223 if (bReadDocInfo && bNewDoc && m_xDocProps.is())
224 ReadInfo();
225 else
226 SkipGroup();
227 break;
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:
235 case RTF_FIELD:
236 case RTF_ATNID:
237 case RTF_ANNOTATION:
239 case RTF_BKMKSTART:
240 case RTF_BKMKEND:
241 case RTF_BKMK_KEY:
242 case RTF_XE:
243 case RTF_TC:
244 case RTF_NEXTFILE:
245 case RTF_TEMPLATE:
246 // RTF_SHPRSLT disabled for #i19718#
247 SkipGroup();
248 break;
249 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
251 case RTF_PGDSCNO:
252 case RTF_PGBRK:
253 case RTF_SHADOW:
254 if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
255 break;
256 nToken = SkipToken( -1 );
257 if( '{' == GetStackPtr( -1 )->nTokenId )
258 nToken = SkipToken( -1 );
260 ReadAttr( nToken, &GetAttrSet() );
261 break;
263 default:
264 switch( nToken & ~(0xff | RTF_SWGDEFS) )
266 case RTF_PARFMT: // hier gibts keine Swg-Defines
267 ReadAttr( nToken, &GetAttrSet() );
268 break;
270 case RTF_CHRFMT:
271 case RTF_BRDRDEF:
272 case RTF_TABSTOPDEF:
274 if( RTF_SWGDEFS & nToken)
276 if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
277 break;
278 nToken = SkipToken( -1 );
279 if( '{' == GetStackPtr( -1 )->nTokenId )
281 nToken = SkipToken( -1 );
284 ReadAttr( nToken, &GetAttrSet() );
285 break;
286 default:
288 if( /*( '{' == GetStackPtr( -1 )->nTokenId ) ||*/
289 ( RTF_IGNOREFLAG == GetStackPtr( -1 )->nTokenId &&
290 '{' == GetStackPtr( -2 )->nTokenId ) )
291 SkipGroup();
293 break;
295 break;
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 );
319 break;
320 case '{':
322 if( RTF_IGNOREFLAG != GetNextToken() )
323 nToken = SkipToken( -1 );
324 else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
325 RTF_PN != nToken )
326 nToken = SkipToken( -2 );
327 else
329 // filter out at once
330 ReadUnknownData();
331 nToken = GetNextToken();
332 if( '}' != nToken )
333 eState = SVPAR_ERROR;
334 break;
336 ++_nOpenBrakets;
338 break;
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;
345 bHasStyleNo = true;
346 break;
347 case RTF_CS: nStyleNo = (short)nTokenValue;
348 bHasStyleNo = true;
349 pStyle->bIsCharFmt = true;
350 break;
352 case RTF_TEXTTOKEN:
353 if (bHasStyleNo)
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() );
365 nStyleNo = 0;
366 bHasStyleNo = false;
368 break;
369 default:
370 switch( nToken & ~(0xff | RTF_SWGDEFS) )
372 case RTF_PARFMT: // hier gibts keine Swg-Defines
373 ReadAttr( nToken, &pStyle->aAttrSet );
374 break;
376 case RTF_CHRFMT:
377 case RTF_BRDRDEF:
378 case RTF_TABSTOPDEF:
380 if( RTF_SWGDEFS & nToken)
382 if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
383 break;
384 nToken = SkipToken( -1 );
385 if( '{' == GetStackPtr( -1 )->nTokenId )
387 nToken = SkipToken( -1 );
390 ReadAttr( nToken, &pStyle->aAttrSet );
391 break;
393 break;
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()
406 int nToken;
407 sal_uInt8 nRed = 0xff, nGreen = 0xff, nBlue = 0xff;
409 while( '}' != ( nToken = GetNextToken() ) && IsParserWorking() )
411 switch( nToken )
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;
417 case RTF_TEXTTOKEN:
418 if( 1 == aToken.getLength()
419 ? aToken[ 0 ] != ';'
420 : -1 == aToken.indexOf( ";" ) )
421 break; // At least the ';' must be found
423 // else no break !!
425 case ';':
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 );
441 break;
444 SkipToken( -1 ); // the closing brace is evaluated "above"
447 void SvxRTFParser::ReadFontTable()
449 int nToken = 0;
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() ))
465 case '}':
466 bIsAltFntNm = false;
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;
473 break;
474 case '{':
475 if( RTF_IGNOREFLAG != GetNextToken() )
476 nToken = SkipToken( -1 );
477 // immediately skip unknown and all known but non-evaluated
478 // groups
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 );
483 else
485 // filter out at once
486 ReadUnknownData();
487 nToken = GetNextToken();
488 if( '}' != nToken )
489 eState = SVPAR_ERROR;
490 break;
492 ++_nOpenBrakets;
493 break;
494 case RTF_FROMAN:
495 pFont->SetFamily( FAMILY_ROMAN );
496 break;
497 case RTF_FSWISS:
498 pFont->SetFamily( FAMILY_SWISS );
499 break;
500 case RTF_FMODERN:
501 pFont->SetFamily( FAMILY_MODERN );
502 break;
503 case RTF_FSCRIPT:
504 pFont->SetFamily( FAMILY_SCRIPT );
505 break;
506 case RTF_FDECOR:
507 pFont->SetFamily( FAMILY_DECORATIVE );
508 break;
509 // for technical/symbolic font of the rtl_TextEncoding is changed!
510 case RTF_FTECH:
511 pFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
512 // deliberate fall through
513 case RTF_FNIL:
514 pFont->SetFamily( FAMILY_DONTKNOW );
515 break;
516 case RTF_FCHARSET:
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);
528 break;
529 case RTF_FPRQ:
530 switch( nTokenValue )
532 case 1:
533 pFont->SetPitch( PITCH_FIXED );
534 break;
535 case 2:
536 pFont->SetPitch( PITCH_VARIABLE );
537 break;
539 break;
540 case RTF_F:
541 bCheckNewFont = true;
542 nInsFontNo = nFontNo;
543 nFontNo = (short)nTokenValue;
544 break;
545 case RTF_FALT:
546 bIsAltFntNm = true;
547 break;
548 case RTF_TEXTTOKEN:
549 DelCharAtEnd( aToken, ';' );
550 if ( !aToken.isEmpty() )
552 if( bIsAltFntNm )
553 sAltNm = aToken;
554 else
555 sFntNm = aToken;
557 break;
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 );
570 sAltNm.clear();
571 sFntNm.clear();
574 // the last one we have to delete manually
575 delete pFont;
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 )
595 rStr.clear();
596 int _nOpenBrakets = 1, nToken = 0; // the first was already detected earlier!!
598 while( _nOpenBrakets && IsParserWorking() )
600 switch( nToken = GetNextToken() )
602 case '}': --_nOpenBrakets; break;
603 case '{':
605 if( RTF_IGNOREFLAG != GetNextToken() )
606 nToken = SkipToken( -1 );
607 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
608 nToken = SkipToken( -2 );
609 else
611 // filter out at once
612 ReadUnknownData();
613 nToken = GetNextToken();
614 if( '}' != nToken )
615 eState = SVPAR_ERROR;
616 break;
618 ++_nOpenBrakets;
620 break;
622 case RTF_TEXTTOKEN:
623 rStr += aToken;
624 break;
627 SkipToken( -1 ); // the closing brace is evaluated "above"
628 return rStr;
631 util::DateTime SvxRTFParser::GetDateTimeStamp( )
633 util::DateTime aDT;
634 bool bContinue = true;
636 while( bContinue && IsParserWorking() )
638 int nToken = GetNextToken();
639 switch( nToken )
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;
646 default:
647 bContinue = false;
650 SkipToken( -1 ); // the closing brace is evaluated "above"
651 return aDT;
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;
660 long nVersNo = 0;
662 while( _nOpenBrakets && IsParserWorking() )
664 switch( nToken = GetNextToken() )
666 case '}': --_nOpenBrakets; break;
667 case '{':
669 if( RTF_IGNOREFLAG != GetNextToken() )
670 nToken = SkipToken( -1 );
671 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
672 nToken = SkipToken( -2 );
673 else
675 // filter out at once
676 ReadUnknownData();
677 nToken = GetNextToken();
678 if( '}' != nToken )
679 eState = SVPAR_ERROR;
680 break;
682 ++_nOpenBrakets;
684 break;
686 case RTF_TITLE:
687 m_xDocProps->setTitle( GetTextToEndGroup( sStr ) );
688 break;
689 case RTF_SUBJECT:
690 m_xDocProps->setSubject( GetTextToEndGroup( sStr ) );
691 break;
692 case RTF_AUTHOR:
693 m_xDocProps->setAuthor( GetTextToEndGroup( sStr ) );
694 break;
695 case RTF_OPERATOR:
696 m_xDocProps->setModifiedBy( GetTextToEndGroup( sStr ) );
697 break;
698 case RTF_KEYWORDS:
700 OUString sTemp = GetTextToEndGroup( sStr );
701 m_xDocProps->setKeywords(
702 ::comphelper::string::convertCommaSeparated(sTemp) );
703 break;
705 case RTF_DOCCOMM:
706 m_xDocProps->setDescription( GetTextToEndGroup( sStr ) );
707 break;
709 case RTF_HLINKBASE:
710 sBaseURL = GetTextToEndGroup( sStr ) ;
711 break;
713 case RTF_CREATIM:
714 m_xDocProps->setCreationDate( GetDateTimeStamp() );
715 break;
717 case RTF_REVTIM:
718 m_xDocProps->setModificationDate( GetDateTimeStamp() );
719 break;
721 case RTF_PRINTIM:
722 m_xDocProps->setPrintDate( GetDateTimeStamp() );
723 break;
725 case RTF_COMMENT:
726 GetTextToEndGroup( sComment );
727 break;
729 case RTF_BUPTIM:
730 SkipGroup();
731 break;
733 case RTF_VERN:
734 nVersNo = nTokenValue;
735 break;
737 case RTF_EDMINS:
738 case RTF_ID:
739 case RTF_VERSION:
740 case RTF_NOFPAGES:
741 case RTF_NOFWORDS:
742 case RTF_NOFCHARS:
743 NextToken( nToken );
744 break;
746 // default:
750 if( pChkForVerNo &&
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()
769 aFontTbl.clear();
772 void SvxRTFParser::ClearStyleTbl()
774 aStyleTbl.clear();
777 void SvxRTFParser::ClearAttrStack()
779 SvxRTFItemStackType* pTmp;
780 for( size_t nCnt = aAttrStack.size(); nCnt; --nCnt )
782 pTmp = aAttrStack.back();
783 aAttrStack.pop_back();
784 delete pTmp;
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 );
796 return rStr;
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() );
810 pFont = pDfltFont;
812 else
813 pFont = it->second;
814 return *pFont;
817 SvxRTFItemStackType* SvxRTFParser::_GetAttrSet( bool const bCopyAttr )
819 SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
820 SvxRTFItemStackType* pNew;
821 if( pAkt )
822 pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, bCopyAttr );
823 else
824 pNew = new SvxRTFItemStackType( *pAttrPool, &aWhichMap[0],
825 *pInsPos );
826 pNew->SetRTFDefaults( GetRTFDefaults() );
828 aAttrStack.push_back( pNew );
829 bNewGroup = false;
830 return 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
855 else
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;
899 while( true )
901 if( SfxItemState::SET == pAkt->aAttrSet.GetItemState(
902 pItem->Which(), false, &pGet ) &&
903 *pItem == *pGet )
904 pOld->aAttrSet.ClearItem( pItem->Which() );
906 if( aIter.IsAtEnd() )
907 break;
908 pItem = aIter.NextItem();
911 if( !pOld->aAttrSet.Count() && !pOld->pChildList &&
912 !pOld->nStyleNo )
913 break;
916 // Set all attributes which have been defined from start until here
917 bool bCrsrBack = !pInsPos->GetCntIdx();
918 if( bCrsrBack )
920 // at the beginning of a paragraph? Move back one position
921 sal_Int32 nNd = pInsPos->GetNodeIdx();
922 MovePos(false);
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() ))
932 if( !bCrsrBack )
934 // all pard attributes are only valid until the previous
935 // paragraph !!
936 if( nOldSttNdIdx == pInsPos->GetNodeIdx() )
939 else
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() );
956 // Were there any?
957 if( pNew->aAttrSet.Count() == pOld->aAttrSet.Count() )
958 delete pNew;
959 else
961 pNew->nStyleNo = 0;
963 // Now span the real area of pNew from old
964 SetEndPrevPara( pOld->pEndNd, pOld->nEndCnt );
965 pNew->nSttCnt = 0;
967 if( IsChkStyleAttr() )
969 _ClearStyleAttr( *pOld );
970 _ClearStyleAttr( *pNew ); //#i10381#, methinks.
973 if( pAkt )
975 pAkt->Add( pOld );
976 pAkt->Add( pNew );
978 else
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
987 break;
992 pOld->pEndNd = pInsPos->MakeNodeIdx();
993 pOld->nEndCnt = pInsPos->GetCntIdx();
996 #i21422#
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 );
1008 if( pAkt )
1010 pAkt->Add( 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
1016 MovePos(true);
1017 bCrsrBack = false;
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
1025 AttrGroupEnd();
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 );
1029 pAkt = pNew;
1032 else
1033 // Last off the stack, thus cache it until the next text was
1034 // read. (Span no attributes!)
1035 aAttrSetList.push_back( pOld );
1037 pOld = 0;
1040 if( bCrsrBack )
1041 // at the beginning of a paragraph? Move back one position
1042 MovePos(true);
1044 } while( false );
1046 if( pOld )
1047 delete pOld;
1049 bNewGroup = false;
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() )
1057 AttrGroupEnd();
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()
1100 aWhichMap.clear();
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()
1112 if( !pRTFDefaults )
1114 pRTFDefaults = new SfxItemSet( *pAttrPool, &aWhichMap[0] );
1115 sal_uInt16 nId;
1116 if( 0 != ( nId = aPardMap.nScriptSpace ))
1118 SvxScriptSpaceItem aItem( false, nId );
1119 if( bNewDoc )
1120 pAttrPool->SetPoolDefaultItem( aItem );
1121 else
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
1133 nBasedOn = 0;
1134 bBasedOnIsSet = false; //$flr #117411#
1135 nNext = 0;
1136 bIsCharFmt = false;
1140 SvxRTFItemStackType::SvxRTFItemStackType(
1141 SfxItemPool& rPool, const sal_uInt16* pWhichRange,
1142 const SvxPosition& rPos )
1143 : aAttrSet( rPool, pWhichRange ),
1144 pChildList( 0 ),
1145 nStyleNo( 0 )
1147 pSttNd = rPos.MakeNodeIdx();
1148 nSttCnt = rPos.GetCntIdx();
1149 pEndNd = pSttNd;
1150 nEndCnt = nSttCnt;
1153 SvxRTFItemStackType::SvxRTFItemStackType(
1154 const SvxRTFItemStackType& rCpy,
1155 const SvxPosition& rPos,
1156 bool const bCopyAttr )
1157 : aAttrSet( *rCpy.aAttrSet.GetPool(), rCpy.aAttrSet.GetRanges() ),
1158 pChildList( 0 ),
1159 nStyleNo( rCpy.nStyleNo )
1161 pSttNd = rPos.MakeNodeIdx();
1162 nSttCnt = rPos.GetCntIdx();
1163 pEndNd = pSttNd;
1164 nEndCnt = nSttCnt;
1166 aAttrSet.SetParent( &rCpy.aAttrSet );
1167 if( bCopyAttr )
1168 aAttrSet.Put( rCpy.aAttrSet );
1171 SvxRTFItemStackType::~SvxRTFItemStackType()
1173 if( pChildList )
1174 delete pChildList;
1175 if( pSttNd != pEndNd )
1176 delete pEndNd;
1177 delete pSttNd;
1180 void SvxRTFItemStackType::Add( SvxRTFItemStackType* pIns )
1182 if( !pChildList )
1183 pChildList = new SvxRTFItemStackList();
1184 pChildList->push_back( pIns );
1187 void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos )
1189 if (pSttNd != pEndNd)
1190 delete pEndNd;
1191 delete pSttNd;
1192 pSttNd = rPos.MakeNodeIdx();
1193 pEndNd = pSttNd;
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())
1204 delete pSttNd;
1205 pSttNd = rNewNode.Clone();
1206 if (bSameEndAsStart)
1207 pEndNd = pSttNd;
1210 if (!bSameEndAsStart && GetEndNodeIdx() == rOldNode.GetIdx())
1212 delete pEndNd;
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");
1230 sal_uInt16 n;
1231 SvxRTFItemStackType* pTmp = &(*pChildList)[0];
1233 if( !pTmp->aAttrSet.Count() ||
1234 pSttNd->GetIdx() != pTmp->pSttNd->GetIdx() ||
1235 nSttCnt != pTmp->nSttCnt )
1236 return;
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 );
1248 if( !pTmp->nSttCnt
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 );
1257 return;
1260 if( n )
1262 // Search for all which are set over the whole area
1263 SfxItemIter aIter( aMrgSet );
1264 const SfxPoolItem* pItem;
1265 do {
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() )
1272 break;
1273 aIter.NextItem();
1274 } while( true );
1276 if( !aMrgSet.Count() )
1277 return;
1280 pLastNd = pTmp->pEndNd;
1281 nLastCnt = pTmp->nEndCnt;
1284 if( pEndNd->GetIdx() != pLastNd->GetIdx() || nEndCnt != nLastCnt )
1285 return;
1287 // It can be merged
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 );
1298 --n;
1301 if( pChildList->empty() )
1303 delete pChildList;
1304 pChildList = 0;
1307 void SvxRTFItemStackType::SetRTFDefaults( const SfxItemSet& rDefaults )
1309 if( rDefaults.Count() )
1311 SfxItemIter aIter( rDefaults );
1312 do {
1313 sal_uInt16 nWhich = aIter.GetCurItem()->Which();
1314 if( SfxItemState::SET != aAttrSet.GetItemState( nWhich, false ))
1315 aAttrSet.Put( *aIter.GetCurItem() );
1317 if( aIter.IsAtEnd() )
1318 break;
1319 aIter.NextItem();
1320 } while( true );
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: */