xref: /aoo41x/main/editeng/source/rtf/svxrtf.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_editeng.hxx"
30 
31 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
32 
33 
34 #include <ctype.h>
35 #include <tools/datetime.hxx>
36 #include <rtl/tencinfo.h>
37 #include <svl/itemiter.hxx>
38 #include <svl/whiter.hxx>
39 #include <svtools/rtftoken.h>
40 #include <svl/itempool.hxx>
41 
42 #include <comphelper/string.hxx>
43 
44 #include <com/sun/star/lang/Locale.hpp>
45 #include <editeng/scriptspaceitem.hxx>
46 #include <editeng/fontitem.hxx>
47 #include <editeng/colritem.hxx>
48 #include <editeng/svxrtf.hxx>
49 #include <editeng/editids.hrc>
50 #include <vcl/svapp.hxx>
51 
52 #include <com/sun/star/document/XDocumentProperties.hpp>
53 
54 
55 using namespace ::com::sun::star;
56 
57 
58 SV_IMPL_PTRARR( SvxRTFItemStackList, SvxRTFItemStackType* )
59 
60 CharSet lcl_GetDefaultTextEncodingForRTF()
61 {
62 
63     ::com::sun::star::lang::Locale aLocale;
64     ::rtl::OUString aLangString;
65 
66     aLocale = Application::GetSettings().GetLocale();
67     aLangString = aLocale.Language;
68 
69     if ( aLangString.equals( ::rtl::OUString::createFromAscii( "ru" ) )
70       || aLangString.equals( ::rtl::OUString::createFromAscii( "uk" ) ) )
71         return RTL_TEXTENCODING_MS_1251;
72     if ( aLangString.equals( ::rtl::OUString::createFromAscii( "tr" ) ) )
73         return RTL_TEXTENCODING_MS_1254;
74     else
75         return RTL_TEXTENCODING_MS_1252;
76 }
77 
78 // -------------- Methoden --------------------
79 
80 SvxRTFParser::SvxRTFParser( SfxItemPool& rPool, SvStream& rIn,
81             uno::Reference<document::XDocumentProperties> i_xDocProps,
82             int bReadNewDoc )
83 	: SvRTFParser( rIn, 5 ),
84     rStrm(rIn),
85 	aFontTbl( 16, 4 ),
86 	pInsPos( 0 ),
87 	pAttrPool( &rPool ),
88 	m_xDocProps( i_xDocProps ),
89 	pRTFDefaults( 0 ),
90 	nVersionNo( 0 )
91 {
92 	bNewDoc = bReadNewDoc;
93 
94 	bChkStyleAttr = bCalcValue = bReadDocInfo = bIsInReadStyleTab = sal_False;
95 	bIsLeftToRightDef = sal_True;
96 
97 	{
98 		RTFPlainAttrMapIds aTmp( rPool );
99 		aPlainMap.Insert( (sal_uInt16*)&aTmp,
100 					sizeof( RTFPlainAttrMapIds ) / sizeof(sal_uInt16), 0 );
101 	}
102 	{
103 		RTFPardAttrMapIds aTmp( rPool );
104 		aPardMap.Insert( (sal_uInt16*)&aTmp,
105 					sizeof( RTFPardAttrMapIds ) / sizeof(sal_uInt16), 0 );
106 	}
107 	pDfltFont = new Font;
108 	pDfltColor = new Color;
109 }
110 
111 void SvxRTFParser::EnterEnvironment()
112 {
113 }
114 
115 void SvxRTFParser::LeaveEnvironment()
116 {
117 }
118 
119 void SvxRTFParser::ResetPard()
120 {
121 }
122 
123 SvxRTFParser::~SvxRTFParser()
124 {
125 	if( !aColorTbl.empty() )
126 		ClearColorTbl();
127 	if( aFontTbl.Count() )
128 		ClearFontTbl();
129 	if( aStyleTbl.Count() )
130 		ClearStyleTbl();
131 	if( !aAttrStack.empty() )
132 		ClearAttrStack();
133 
134 	delete pRTFDefaults;
135 
136 	delete pInsPos;
137 	delete pDfltFont;
138 	delete pDfltColor;
139 }
140 
141 void SvxRTFParser::SetInsPos( const SvxPosition& rNew )
142 {
143 	if( pInsPos )
144 		delete pInsPos;
145 	pInsPos = rNew.Clone();
146 }
147 
148 SvParserState SvxRTFParser::CallParser()
149 {
150 	DBG_ASSERT( pInsPos, "no insertion" );
151 
152 	if( !pInsPos )
153 		return SVPAR_ERROR;
154 
155 	if( !aColorTbl.empty() )
156 		ClearColorTbl();
157 	if( aFontTbl.Count() )
158 		ClearFontTbl();
159 	if( aStyleTbl.Count() )
160 		ClearStyleTbl();
161 	if( !aAttrStack.empty() )
162 		ClearAttrStack();
163 
164 	bIsSetDfltTab = sal_False;
165 	bNewGroup = sal_False;
166 	nDfltFont = 0;
167 
168 	sBaseURL.Erase();
169 
170 	// erzeuge aus den gesetzten WhichIds die richtige WhichId-Tabelle.
171 	BuildWhichTbl();
172 
173 	return SvRTFParser::CallParser();
174 }
175 
176 void SvxRTFParser::Continue( int nToken )
177 {
178 	SvRTFParser::Continue( nToken );
179 
180 	if( SVPAR_PENDING != GetStatus() )
181 	{
182 		SetAllAttrOfStk();
183 #if 0
184     //Regardless of what "color 0" is, word defaults to auto as the default colour.
185     //e.g. see #i7713#
186 		if( bNewDoc && ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nColor )
187 			pAttrPool->SetPoolDefaultItem( SvxColorItem( GetColor( 0 ),
188 						((RTFPlainAttrMapIds*)aPlainMap.GetData())->nColor ));
189 #endif
190 	 }
191 }
192 
193 
194 // wird fuer jedes Token gerufen, das in CallParser erkannt wird
195 void SvxRTFParser::NextToken( int nToken )
196 {
197 	sal_Unicode cCh;
198 	switch( nToken )
199 	{
200 	case RTF_COLORTBL:		ReadColorTable();		break;
201 	case RTF_FONTTBL:		ReadFontTable();		break;
202 	case RTF_STYLESHEET:	ReadStyleTable();		break;
203 
204 	case RTF_DEFF:
205 			if( bNewDoc )
206 			{
207 				if( aFontTbl.Count() )
208 					// koennen wir sofort setzen
209 					SetDefault( nToken, nTokenValue );
210 				else
211 					// wird nach einlesen der Fonttabelle gesetzt
212 					nDfltFont = int(nTokenValue);
213 			}
214 			break;
215 
216 	case RTF_DEFTAB:
217 	case RTF_DEFLANG:
218 			if( bNewDoc )
219 				SetDefault( nToken, nTokenValue );
220 			break;
221 
222 
223 	case RTF_PICT:			ReadBitmapData();		break;
224 
225 	case RTF_LINE:			cCh = '\n';	goto INSINGLECHAR;
226 	case RTF_TAB:			cCh = '\t';	goto INSINGLECHAR;
227 	case RTF_SUBENTRYINDEX:	cCh = ':';	goto INSINGLECHAR;
228 
229 	case RTF_EMDASH:		cCh = 151;	goto INSINGLECHAR;
230 	case RTF_ENDASH:		cCh = 150;	goto INSINGLECHAR;
231 	case RTF_BULLET:		cCh = 149;	goto INSINGLECHAR;
232 	case RTF_LQUOTE:		cCh = 145;	goto INSINGLECHAR;
233 	case RTF_RQUOTE:		cCh = 146;	goto INSINGLECHAR;
234 	case RTF_LDBLQUOTE:		cCh = 147;	goto INSINGLECHAR;
235 	case RTF_RDBLQUOTE:		cCh = 148;	goto INSINGLECHAR;
236 INSINGLECHAR:
237 		aToken = ByteString::ConvertToUnicode( (sal_Char)cCh,
238 											RTL_TEXTENCODING_MS_1252 );
239 
240 		// kein Break, aToken wird als Text gesetzt
241 	case RTF_TEXTTOKEN:
242 		{
243 			InsertText();
244 			// alle angesammelten Attribute setzen
245 			for( sal_uInt16 n = aAttrSetList.Count(); n; )
246 			{
247 				SvxRTFItemStackType* pStkSet = aAttrSetList[--n];
248 				SetAttrSet( *pStkSet );
249 				aAttrSetList.DeleteAndDestroy( n );
250 			}
251 		}
252 		break;
253 
254 
255 	case RTF_PAR:
256 		InsertPara();
257 		break;
258 	case '{':
259 		if (bNewGroup)			// Verschachtelung !!
260             _GetAttrSet();
261         EnterEnvironment();
262 		bNewGroup = true;
263 		break;
264 	case '}':
265 		if( !bNewGroup )		// leere Gruppe ??
266 			AttrGroupEnd();
267         LeaveEnvironment();
268 		bNewGroup = false;
269 		break;
270 	case RTF_INFO:
271 #ifndef SVX_LIGHT
272 		if (bReadDocInfo && bNewDoc && m_xDocProps.is())
273 			ReadInfo();
274 		else
275 #endif
276 			SkipGroup();
277 		break;
278 
279 	// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
280 	// erstmal gesamt ueberlesen (muessen alle in einer Gruppe stehen !!)
281 	// Koennen auch ohne dem IGNORE-Flag im RTF-File auftreten; alle Gruppen
282 	// mit IGNORE-Flag werden im default-Zweig ueberlesen.
283 
284 	case RTF_SWG_PRTDATA:
285 	case RTF_FIELD:
286 	case RTF_ATNID:
287 	case RTF_ANNOTATION:
288 
289 	case RTF_BKMKSTART:
290 	case RTF_BKMKEND:
291 	case RTF_BKMK_KEY:
292 	case RTF_XE:
293 	case RTF_TC:
294 	case RTF_NEXTFILE:
295 	case RTF_TEMPLATE:
296 #if 0
297     //disabled for #i19718#
298 	case RTF_SHPRSLT:	// RTF_SHP fehlt noch !!
299 #endif
300 							SkipGroup();
301 							break;
302 	// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
303 
304 	case RTF_PGDSCNO:
305 	case RTF_PGBRK:
306 	case RTF_SHADOW:
307 			if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
308 				break;
309 			nToken = SkipToken( -1 );
310 			if( '{' == GetStackPtr( -1 )->nTokenId )
311 				nToken = SkipToken( -1 );
312 
313 			ReadAttr( nToken, &GetAttrSet() );
314 			break;
315 
316 	default:
317 		switch( nToken & ~(0xff | RTF_SWGDEFS) )
318 		{
319 		case RTF_PARFMT:		// hier gibts keine Swg-Defines
320 			ReadAttr( nToken, &GetAttrSet() );
321 			break;
322 
323 		case RTF_CHRFMT:
324 		case RTF_BRDRDEF:
325 		case RTF_TABSTOPDEF:
326 
327 			if( RTF_SWGDEFS & nToken)
328 			{
329 				if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
330 					break;
331 				nToken = SkipToken( -1 );
332 				if( '{' == GetStackPtr( -1 )->nTokenId )
333 				{
334 					nToken = SkipToken( -1 );
335 				}
336 			}
337 			ReadAttr( nToken, &GetAttrSet() );
338 			break;
339 		default:
340 			{
341 				if( /*( '{' == GetStackPtr( -1 )->nTokenId ) ||*/
342 					( RTF_IGNOREFLAG == GetStackPtr( -1 )->nTokenId &&
343 					  '{' == GetStackPtr( -2 )->nTokenId ) )
344 					SkipGroup();
345 			}
346 			break;
347 		}
348 		break;
349 	}
350 }
351 
352 void SvxRTFParser::ReadStyleTable()
353 {
354 	int nToken, bSaveChkStyleAttr = bChkStyleAttr;
355 	short nStyleNo = 0;
356 	int _nOpenBrakets = 1;		// die erste wurde schon vorher erkannt !!
357 	SvxRTFStyleType* pStyle = new SvxRTFStyleType( *pAttrPool, aWhichMap.GetData() );
358 	pStyle->aAttrSet.Put( GetRTFDefaults() );
359 
360 	bIsInReadStyleTab = sal_True;
361 	bChkStyleAttr = sal_False;		// Attribute nicht gegen die Styles checken
362 
363 	while( _nOpenBrakets && IsParserWorking() )
364 	{
365 		switch( nToken = GetNextToken() )
366 		{
367 		case '}':		if( --_nOpenBrakets && IsParserWorking() )
368 							// Style konnte vollstaendig gelesen werden,
369 							// also ist das noch ein stabiler Status
370 							SaveState( RTF_STYLESHEET );
371 						break;
372 		case '{':
373 			{
374 				if( RTF_IGNOREFLAG != GetNextToken() )
375 					nToken = SkipToken( -1 );
376 				else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
377 							RTF_PN != nToken )
378 					nToken = SkipToken( -2 );
379 				else
380 				{
381 					// gleich herausfiltern
382 					ReadUnknownData();
383 					nToken = GetNextToken();
384 					if( '}' != nToken )
385 						eState = SVPAR_ERROR;
386 					break;
387 				}
388 				++_nOpenBrakets;
389 			}
390 			break;
391 
392 		case RTF_SBASEDON:	pStyle->nBasedOn = sal_uInt16(nTokenValue); pStyle->bBasedOnIsSet=sal_True;	break;
393 		case RTF_SNEXT:		pStyle->nNext = sal_uInt16(nTokenValue);   	break;
394 		case RTF_OUTLINELEVEL:
395 		case RTF_SOUTLVL:	pStyle->nOutlineNo = sal_uInt8(nTokenValue);	break;
396 		case RTF_S:			nStyleNo = (short)nTokenValue;			break;
397 		case RTF_CS:		nStyleNo = (short)nTokenValue;
398 							pStyle->bIsCharFmt = sal_True;
399 							break;
400 
401 		case RTF_TEXTTOKEN:
402 			{
403 				pStyle->sName = DelCharAtEnd( aToken, ';' );
404 
405 /*
406 ??? soll man das umsetzen ???
407 				if( !pStyle->sName.Len() )
408 					pStyle->sName = "Standard";
409 */
410 				// sollte die Nummer doppelt vergeben werden ?
411 				if( aStyleTbl.Count() )
412 				{
413 					SvxRTFStyleType* pOldSt = aStyleTbl.Remove( nStyleNo );
414 					if( pOldSt )
415 						delete pOldSt;
416 				}
417 				// alle Daten vom Style vorhanden, also ab in die Tabelle
418 				aStyleTbl.Insert( nStyleNo, pStyle );
419 				pStyle = new SvxRTFStyleType( *pAttrPool, aWhichMap.GetData() );
420 				pStyle->aAttrSet.Put( GetRTFDefaults() );
421 				nStyleNo = 0;
422 			}
423 			break;
424 		default:
425 			switch( nToken & ~(0xff | RTF_SWGDEFS) )
426 			{
427 			case RTF_PARFMT:		// hier gibts keine Swg-Defines
428 				ReadAttr( nToken, &pStyle->aAttrSet );
429 				break;
430 
431 			case RTF_CHRFMT:
432 			case RTF_BRDRDEF:
433 			case RTF_TABSTOPDEF:
434 
435 				if( RTF_SWGDEFS & nToken)
436 				{
437 					if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
438 						break;
439 					nToken = SkipToken( -1 );
440 					if( '{' == GetStackPtr( -1 )->nTokenId )
441 					{
442 						nToken = SkipToken( -1 );
443 #if 0
444 						--_nOpenBrakets;		// korrigieren!!
445 #endif
446 					}
447 				}
448 				ReadAttr( nToken, &pStyle->aAttrSet );
449 				break;
450 			}
451 			break;
452 		}
453 	}
454 	delete pStyle;			// loesche das letze Style
455 	SkipToken( -1 );		// die schliesende Klammer wird "oben" ausgewertet
456 
457 	// Flag wieder auf alten Zustand
458 	bChkStyleAttr = bSaveChkStyleAttr;
459 	bIsInReadStyleTab = sal_False;
460 }
461 
462 void SvxRTFParser::ReadColorTable()
463 {
464 	int nToken;
465 	sal_uInt8 nRed = 0xff, nGreen = 0xff, nBlue = 0xff;
466 
467 	while( '}' != ( nToken = GetNextToken() ) && IsParserWorking() )
468 	{
469 		switch( nToken )
470 		{
471 		case RTF_RED:	nRed = sal_uInt8(nTokenValue);		break;
472 		case RTF_GREEN:	nGreen = sal_uInt8(nTokenValue);		break;
473 		case RTF_BLUE:	nBlue = sal_uInt8(nTokenValue);		break;
474 
475 		case RTF_TEXTTOKEN:		// oder sollte irgendein Unsin darumstehen?
476 			if( 1 == aToken.Len()
477 					? aToken.GetChar( 0 ) != ';'
478 					: STRING_NOTFOUND == aToken.Search( ';' ) )
479 				break;		// es muss zumindestens das ';' gefunden werden
480 
481 			// else kein break !!
482 
483 		case ';':
484 			if( IsParserWorking() )
485 			{
486 				// eine Farbe ist Fertig, in die Tabelle eintragen
487 				// versuche die Werte auf SV interne Namen zu mappen
488 				ColorPtr pColor = new Color( nRed, nGreen, nBlue );
489 				if( aColorTbl.empty() &&
490 					sal_uInt8(-1) == nRed && sal_uInt8(-1) == nGreen && sal_uInt8(-1) == nBlue )
491 					pColor->SetColor( COL_AUTO );
492 				aColorTbl.push_back( pColor );
493 				nRed = 0, nGreen = 0, nBlue = 0;
494 
495 				// Color konnte vollstaendig gelesen werden,
496 				// also ist das noch ein stabiler Status
497 				SaveState( RTF_COLORTBL );
498 			}
499 			break;
500 		}
501 	}
502 	SkipToken( -1 );		// die schliesende Klammer wird "oben" ausgewertet
503 }
504 
505 void SvxRTFParser::ReadFontTable()
506 {
507 	int nToken;
508 	int _nOpenBrakets = 1;		// die erste wurde schon vorher erkannt !!
509 	Font* pFont = new Font();
510 	short nFontNo(0), nInsFontNo (0);
511 	String sAltNm, sFntNm;
512 	sal_Bool bIsAltFntNm = sal_False, bCheckNewFont;
513 
514     CharSet nSystemChar = lcl_GetDefaultTextEncodingForRTF();
515     pFont->SetCharSet( nSystemChar );
516     SetEncoding( nSystemChar );
517 
518 	while( _nOpenBrakets && IsParserWorking() )
519 	{
520 		bCheckNewFont = sal_False;
521 		switch( ( nToken = GetNextToken() ))
522 		{
523 		    case '}':
524 				bIsAltFntNm = sal_False;
525 				// Style konnte vollstaendig gelesen werden,
526 				// also ist das noch ein stabiler Status
527 				if( --_nOpenBrakets <= 1 && IsParserWorking() )
528 				    SaveState( RTF_FONTTBL );
529 				bCheckNewFont = sal_True;
530 				nInsFontNo = nFontNo;
531 				break;
532 		    case '{':
533 				if( RTF_IGNOREFLAG != GetNextToken() )
534 					nToken = SkipToken( -1 );
535 				// Unknown und alle bekannten nicht ausgewerteten Gruppen
536 				// sofort ueberspringen
537 				else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
538 						RTF_PANOSE != nToken && RTF_FNAME != nToken &&
539 						RTF_FONTEMB != nToken && RTF_FONTFILE != nToken )
540 					nToken = SkipToken( -2 );
541 				else
542 				{
543 					// gleich herausfiltern
544 					ReadUnknownData();
545 					nToken = GetNextToken();
546 					if( '}' != nToken )
547 						eState = SVPAR_ERROR;
548 					break;
549 				}
550 				++_nOpenBrakets;
551 			    break;
552 		    case RTF_FROMAN:
553                 pFont->SetFamily( FAMILY_ROMAN );
554                 break;
555 		    case RTF_FSWISS:
556                 pFont->SetFamily( FAMILY_SWISS );
557                 break;
558 		    case RTF_FMODERN:
559                 pFont->SetFamily( FAMILY_MODERN );
560                 break;
561 		    case RTF_FSCRIPT:
562                 pFont->SetFamily( FAMILY_SCRIPT );
563                 break;
564 		    case RTF_FDECOR:
565                 pFont->SetFamily( FAMILY_DECORATIVE );
566                 break;
567 		    // bei technischen/symbolischen Font wird der CharSet ungeschaltet!!
568 		    case RTF_FTECH:
569                 pFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
570                 // deliberate fall through
571 		    case RTF_FNIL:
572                 pFont->SetFamily( FAMILY_DONTKNOW );
573                 break;
574 		    case RTF_FCHARSET:
575 			    if (-1 != nTokenValue)
576                 {
577                     CharSet nCharSet = rtl_getTextEncodingFromWindowsCharset(
578                         (sal_uInt8)nTokenValue);
579 				    pFont->SetCharSet(nCharSet);
580                     //When we're in a font, the fontname is in the font
581                     //charset, except for symbol fonts I believe
582                     if (nCharSet == RTL_TEXTENCODING_SYMBOL)
583                         nCharSet = RTL_TEXTENCODING_DONTKNOW;
584                     SetEncoding(nCharSet);
585                 }
586 			    break;
587 		    case RTF_FPRQ:
588 			    switch( nTokenValue )
589 			    {
590 			        case 1:
591                         pFont->SetPitch( PITCH_FIXED );
592                         break;
593 			        case 2:
594                         pFont->SetPitch( PITCH_VARIABLE );
595                         break;
596 			    }
597 			    break;
598 		    case RTF_F:
599 			    bCheckNewFont = sal_True;
600 			    nInsFontNo = nFontNo;
601 			    nFontNo = (short)nTokenValue;
602 			    break;
603 		    case RTF_FALT:
604                 bIsAltFntNm = sal_True;
605                 break;
606 		    case RTF_TEXTTOKEN:
607 				DelCharAtEnd( aToken, ';' );
608 				if ( aToken.Len() )
609 				{
610 					if( bIsAltFntNm )
611 						sAltNm = aToken;
612 					else
613 						sFntNm = aToken;
614 				}
615 			    break;
616 		}
617 
618 		if( bCheckNewFont && 1 >= _nOpenBrakets && sFntNm.Len() )  // one font is ready
619 		{
620 			// alle Daten vom Font vorhanden, also ab in die Tabelle
621 			if (sAltNm.Len())
622 				(sFntNm += ';' ) += sAltNm;
623 
624 			pFont->SetName( sFntNm );
625 			aFontTbl.Insert( nInsFontNo, pFont );
626 			pFont = new Font();
627 			pFont->SetCharSet( nSystemChar );
628 			sAltNm.Erase();
629 			sFntNm.Erase();
630 		}
631 	}
632 	// den letzen muessen wir selbst loeschen
633 	delete pFont;
634 	SkipToken( -1 );		// die schliesende Klammer wird "oben" ausgewertet
635 
636 	// setze den default Font am Doc
637 	if( bNewDoc && IsParserWorking() )
638 		SetDefault( RTF_DEFF, nDfltFont );
639 }
640 
641 void SvxRTFParser::ReadBitmapData()
642 {
643 	SvRTFParser::ReadBitmapData();
644 }
645 
646 void SvxRTFParser::ReadOLEData()
647 {
648 	SvRTFParser::ReadOLEData();
649 }
650 
651 String& SvxRTFParser::GetTextToEndGroup( String& rStr )
652 {
653 	rStr.Erase( 0 );
654 	int _nOpenBrakets = 1, nToken;		// die erste wurde schon vorher erkannt !!
655 
656 	while( _nOpenBrakets && IsParserWorking() )
657 	{
658 		switch( nToken = GetNextToken() )
659 		{
660 		case '}':		--_nOpenBrakets;	break;
661 		case '{':
662 			{
663 				if( RTF_IGNOREFLAG != GetNextToken() )
664 					nToken = SkipToken( -1 );
665 				else if( RTF_UNKNOWNCONTROL != GetNextToken() )
666 					nToken = SkipToken( -2 );
667 				else
668 				{
669 					// gleich herausfiltern
670 					ReadUnknownData();
671 					nToken = GetNextToken();
672 					if( '}' != nToken )
673 						eState = SVPAR_ERROR;
674 					break;
675 				}
676 				++_nOpenBrakets;
677 			}
678 			break;
679 
680 		case RTF_TEXTTOKEN:
681 			rStr += aToken;
682 			break;
683 		}
684 	}
685 	SkipToken( -1 );		// die schliesende Klammer wird "oben" ausgewertet
686 	return rStr;
687 }
688 
689 util::DateTime SvxRTFParser::GetDateTimeStamp( )
690 {
691 	util::DateTime aDT;
692 	sal_Bool bWeiter = sal_True;
693 	int nToken;
694 	while( bWeiter && IsParserWorking() )
695 	{
696 		switch( nToken = GetNextToken() )
697 		{
698 		case RTF_YR:	aDT.Year = (sal_uInt16)nTokenValue;	    break;
699 		case RTF_MO:    aDT.Month = (sal_uInt16)nTokenValue;	break;
700 		case RTF_DY:	aDT.Day = (sal_uInt16)nTokenValue;	    break;
701 		case RTF_HR:	aDT.Hours = (sal_uInt16)nTokenValue;	break;
702 		case RTF_MIN:	aDT.Minutes = (sal_uInt16)nTokenValue;	break;
703 		default:
704 			bWeiter = sal_False;
705 		}
706 	}
707 	SkipToken( -1 );		// die schliesende Klammer wird "oben" ausgewertet
708 	return aDT;
709 }
710 
711 void SvxRTFParser::ReadInfo( const sal_Char* pChkForVerNo )
712 {
713 #ifndef SVX_LIGHT
714 	int _nOpenBrakets = 1, nToken;		// die erste wurde schon vorher erkannt !!
715     DBG_ASSERT(m_xDocProps.is(),
716         "SvxRTFParser::ReadInfo: no DocumentProperties");
717 	String sStr, sComment;
718 	long nVersNo = 0;
719 
720 	while( _nOpenBrakets && IsParserWorking() )
721 	{
722 		switch( nToken = GetNextToken() )
723 		{
724 		case '}':		--_nOpenBrakets;	break;
725 		case '{':
726 			{
727 				if( RTF_IGNOREFLAG != GetNextToken() )
728 					nToken = SkipToken( -1 );
729 				else if( RTF_UNKNOWNCONTROL != GetNextToken() )
730 					nToken = SkipToken( -2 );
731 				else
732 				{
733 					// gleich herausfiltern
734 					ReadUnknownData();
735 					nToken = GetNextToken();
736 					if( '}' != nToken )
737 						eState = SVPAR_ERROR;
738 					break;
739 				}
740 				++_nOpenBrakets;
741 			}
742 			break;
743 
744 		case RTF_TITLE:
745 			m_xDocProps->setTitle( GetTextToEndGroup( sStr ) );
746 			break;
747 		case RTF_SUBJECT:
748 			m_xDocProps->setSubject( GetTextToEndGroup( sStr ) );
749 			break;
750 		case RTF_AUTHOR:
751 			m_xDocProps->setAuthor( GetTextToEndGroup( sStr ) );
752 			break;
753 		case RTF_OPERATOR:
754 			m_xDocProps->setModifiedBy( GetTextToEndGroup( sStr ) );
755 			break;
756 		case RTF_KEYWORDS:
757             {
758                 ::rtl::OUString sTemp = GetTextToEndGroup( sStr );
759                 m_xDocProps->setKeywords(
760                     ::comphelper::string::convertCommaSeparated(sTemp) );
761                 break;
762             }
763 		case RTF_DOCCOMM:
764 			m_xDocProps->setDescription( GetTextToEndGroup( sStr ) );
765 			break;
766 
767 		case RTF_HLINKBASE:
768 			sBaseURL = GetTextToEndGroup( sStr ) ;
769 			break;
770 
771 		case RTF_CREATIM:
772 			m_xDocProps->setCreationDate( GetDateTimeStamp() );
773 			break;
774 
775 		case RTF_REVTIM:
776 			m_xDocProps->setModificationDate( GetDateTimeStamp() );
777 			break;
778 
779 		case RTF_PRINTIM:
780 			m_xDocProps->setPrintDate( GetDateTimeStamp() );
781 			break;
782 
783 		case RTF_COMMENT:
784 			GetTextToEndGroup( sComment );
785 			break;
786 
787 		case RTF_BUPTIM:
788 			SkipGroup();
789 			break;
790 
791 		case RTF_VERN:
792 			nVersNo = nTokenValue;
793 			break;
794 
795 		case RTF_EDMINS:
796 		case RTF_ID:
797 		case RTF_VERSION:
798 		case RTF_NOFPAGES:
799 		case RTF_NOFWORDS:
800 		case RTF_NOFCHARS:
801 			NextToken( nToken );
802 			break;
803 
804 //		default:
805 		}
806 	}
807 
808 	if( pChkForVerNo &&
809 		COMPARE_EQUAL == sComment.CompareToAscii( pChkForVerNo ))
810 		nVersionNo = nVersNo;
811 
812 	SkipToken( -1 );		// die schliesende Klammer wird "oben" ausgewertet
813 #endif
814 }
815 
816 
817 void SvxRTFParser::ClearColorTbl()
818 {
819 	while ( !aColorTbl.empty() )
820     {
821 		delete aColorTbl.back();
822     	aColorTbl.pop_back();
823     }
824 }
825 
826 void SvxRTFParser::ClearFontTbl()
827 {
828 	for( sal_uInt32 nCnt = aFontTbl.Count(); nCnt; )
829 		delete aFontTbl.GetObject( --nCnt );
830 }
831 
832 void SvxRTFParser::ClearStyleTbl()
833 {
834 	for( sal_uInt32 nCnt = aStyleTbl.Count(); nCnt; )
835 		delete aStyleTbl.GetObject( --nCnt );
836 }
837 
838 void SvxRTFParser::ClearAttrStack()
839 {
840 	SvxRTFItemStackType* pTmp;
841 	for( size_t nCnt = aAttrStack.size(); nCnt; --nCnt )
842 	{
843 		pTmp = aAttrStack.back();
844 		aAttrStack.pop_back();
845 		delete pTmp;
846 	}
847 }
848 
849 String& SvxRTFParser::DelCharAtEnd( String& rStr, const sal_Unicode cDel )
850 {
851 	if( rStr.Len() && ' ' == rStr.GetChar( 0 ))
852 		rStr.EraseLeadingChars();
853 	if( rStr.Len() && ' ' == rStr.GetChar( rStr.Len()-1 ))
854 		rStr.EraseTrailingChars();
855 	if( rStr.Len() && cDel == rStr.GetChar( rStr.Len()-1 ))
856 		rStr.Erase( rStr.Len()-1 );
857 	return rStr;
858 }
859 
860 
861 const Font& SvxRTFParser::GetFont( sal_uInt16 nId )
862 {
863 	const Font* pFont = aFontTbl.Get( nId );
864 	if( !pFont )
865 	{
866         const SvxFontItem& rDfltFont = (const SvxFontItem&)
867                         pAttrPool->GetDefaultItem(
868                     ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nFont );
869         pDfltFont->SetName( rDfltFont.GetStyleName() );
870         pDfltFont->SetFamily( rDfltFont.GetFamily() );
871 		pFont = pDfltFont;
872 	}
873 	return *pFont;
874 }
875 
876 SvxRTFItemStackType* SvxRTFParser::_GetAttrSet( int bCopyAttr )
877 {
878     SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
879 	SvxRTFItemStackType* pNew;
880 	if( pAkt )
881 		pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, bCopyAttr );
882 	else
883 		pNew = new SvxRTFItemStackType( *pAttrPool, aWhichMap.GetData(),
884 										*pInsPos );
885 	pNew->SetRTFDefaults( GetRTFDefaults() );
886 
887 	aAttrStack.push_back( pNew );
888 	bNewGroup = sal_False;
889 	return pNew;
890 }
891 
892 
893 void SvxRTFParser::_ClearStyleAttr( SvxRTFItemStackType& rStkType )
894 {
895 	// check attributes to the attributes of the stylesheet or to
896 	// the default attrs of the document
897 	SfxItemSet &rSet = rStkType.GetAttrSet();
898 	const SfxItemPool& rPool = *rSet.GetPool();
899 	const SfxPoolItem* pItem;
900 	SfxWhichIter aIter( rSet );
901 
902 	SvxRTFStyleType* pStyle;
903 	if( !IsChkStyleAttr() ||
904 		!rStkType.GetAttrSet().Count() ||
905 		0 == ( pStyle = aStyleTbl.Get( rStkType.nStyleNo ) ))
906 	{
907 		for( sal_uInt16 nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() )
908 		{
909 			if( SFX_WHICH_MAX > nWhich &&
910 				SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem ) &&
911 					 rPool.GetDefaultItem( nWhich ) == *pItem )
912 				rSet.ClearItem( nWhich );		// loeschen
913 		}
914 	}
915 	else
916 	{
917 		// alle Attribute, die schon vom Style definiert sind, aus dem
918 		// akt. AttrSet entfernen
919 		SfxItemSet &rStyleSet = pStyle->aAttrSet;
920 		const SfxPoolItem* pSItem;
921 		for( sal_uInt16 nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() )
922 		{
923 			if( SFX_ITEM_SET == rStyleSet.GetItemState( nWhich, sal_True, &pSItem ))
924 			{
925 				// JP 22.06.99: im Style und im Set gleich gesetzt -> loeschen
926 				if( SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem )
927 					&& *pItem == *pSItem )
928 					rSet.ClearItem( nWhich );		// loeschen
929 			}
930 				// Bug 59571 - falls nicht im Style gesetzt und gleich mit
931 				// 				dem PoolDefault -> auch dann loeschen
932 			else if( SFX_WHICH_MAX > nWhich &&
933 					SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem ) &&
934 					 rPool.GetDefaultItem( nWhich ) == *pItem )
935 				rSet.ClearItem( nWhich );		// loeschen
936 		}
937 	}
938 }
939 
940 void SvxRTFParser::AttrGroupEnd()	// den akt. Bearbeiten, vom Stack loeschen
941 {
942 	if( !aAttrStack.empty() )
943 	{
944         SvxRTFItemStackType *pOld = aAttrStack.empty() ? 0 : aAttrStack.back();
945 		aAttrStack.pop_back();
946 		SvxRTFItemStackType *pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
947 
948 		do {		// middle check loop
949 			sal_uLong nOldSttNdIdx = pOld->pSttNd->GetIdx();
950 			if( !pOld->pChildList &&
951 				((!pOld->aAttrSet.Count() && !pOld->nStyleNo ) ||
952 				(nOldSttNdIdx == pInsPos->GetNodeIdx() &&
953 				pOld->nSttCnt == pInsPos->GetCntIdx() )))
954 				break;			// keine Attribute oder Bereich
955 
956 			// setze nur die Attribute, die unterschiedlich zum Parent sind
957 			if( pAkt && pOld->aAttrSet.Count() )
958 			{
959 				SfxItemIter aIter( pOld->aAttrSet );
960 				const SfxPoolItem* pItem = aIter.GetCurItem(), *pGet;
961 				while( sal_True )
962 				{
963 					if( SFX_ITEM_SET == pAkt->aAttrSet.GetItemState(
964 						pItem->Which(), sal_False, &pGet ) &&
965 						*pItem == *pGet )
966 						pOld->aAttrSet.ClearItem( pItem->Which() );
967 
968 					if( aIter.IsAtEnd() )
969 						break;
970 					pItem = aIter.NextItem();
971 				}
972 
973 				if( !pOld->aAttrSet.Count() && !pOld->pChildList &&
974 					!pOld->nStyleNo )
975 					break;
976 			}
977 
978 			// setze alle Attribute, die von Start bis hier
979 			// definiert sind.
980 			int bCrsrBack = !pInsPos->GetCntIdx();
981 			if( bCrsrBack )
982 			{
983 				// am Absatzanfang ? eine Position zurueck
984 				sal_uLong nNd = pInsPos->GetNodeIdx();
985 				MovePos( sal_False );
986 				// if can not move backward then later dont move forward !
987 				bCrsrBack = nNd != pInsPos->GetNodeIdx();
988 			}
989 
990 			//Bug #46608#: ungueltige Bereiche ignorieren!
991 			if( ( pOld->pSttNd->GetIdx() < pInsPos->GetNodeIdx() ||
992 				( pOld->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
993 				pOld->nSttCnt <= pInsPos->GetCntIdx() ))
994 #if 0
995 //BUG 68555 - dont test for empty paragraph or any range
996 				&& ( nOldSttNdIdx != pInsPos->GetNodeIdx() ||
997 				pOld->nSttCnt != pInsPos->GetCntIdx() ||
998 				!pOld->nSttCnt )
999 #endif
1000 				)
1001 			{
1002 				if( !bCrsrBack )
1003 				{
1004 					// alle pard-Attribute gelten nur bis zum vorherigen
1005 					// Absatz !!
1006 					if( nOldSttNdIdx == pInsPos->GetNodeIdx() )
1007 					{
1008 #if 0
1009 //BUG 68555 - dont reset pard attrs, if the group not begins not at start of
1010 //				paragraph
1011 						// Bereich innerhalb eines Absatzes:
1012 						// alle Absatz-Attribute und StyleNo loeschen
1013 						// aber nur wenn mitten drin angefangen wurde
1014 						if( pOld->nSttCnt )
1015 						{
1016 							pOld->nStyleNo = 0;
1017 							for( sal_uInt16 n = 0; n < aPardMap.Count() &&
1018 												pOld->aAttrSet.Count(); ++n )
1019 								if( aPardMap[n] )
1020 									pOld->aAttrSet.ClearItem( aPardMap[n] );
1021 
1022 							if( !pOld->aAttrSet.Count() && !pOld->pChildList &&
1023 								!pOld->nStyleNo  )
1024 								break;	// auch dieser verlaesst uns jetzt
1025 						}
1026 #endif
1027 					}
1028 					else
1029 					{
1030 						// jetzt wirds kompliziert:
1031 						// - alle Zeichen-Attribute behalten den Bereich,
1032 						// - alle Absatz-Attribute bekommen den Bereich
1033 						// 			bis zum vorherigen Absatz
1034 						SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
1035 									*pOld, *pInsPos, sal_True );
1036 						pNew->aAttrSet.SetParent( pOld->aAttrSet.GetParent() );
1037 
1038 						// loesche aus pNew alle Absatz Attribute
1039 						for( sal_uInt16 n = 0; n < aPardMap.Count() &&
1040 											pNew->aAttrSet.Count(); ++n )
1041 							if( aPardMap[n] )
1042 								pNew->aAttrSet.ClearItem( aPardMap[n] );
1043 						pNew->SetRTFDefaults( GetRTFDefaults() );
1044 
1045 						// gab es ueberhaupt welche ?
1046 						if( pNew->aAttrSet.Count() == pOld->aAttrSet.Count() )
1047 							delete pNew;		// das wars dann
1048 						else
1049 						{
1050 							pNew->nStyleNo = 0;
1051 
1052 							// spanne jetzt den richtigen Bereich auf
1053 							// pNew von alter
1054 							SetEndPrevPara( pOld->pEndNd, pOld->nEndCnt );
1055 							pNew->nSttCnt = 0;
1056 
1057 							if( IsChkStyleAttr() )
1058                             {
1059 								_ClearStyleAttr( *pOld );
1060                                 _ClearStyleAttr( *pNew );   //#i10381#, methinks.
1061                             }
1062 
1063 							if( pAkt )
1064 							{
1065 								pAkt->Add( pOld );
1066 								pAkt->Add( pNew );
1067 							}
1068 							else
1069 							{
1070 								// letzter vom Stack, also zwischenspeichern, bis der
1071 								// naechste Text eingelesen wurde. (keine Attribute
1072 								// aufspannen!!)
1073 								aAttrSetList.Insert( pOld, aAttrSetList.Count() );
1074 								aAttrSetList.Insert( pNew, aAttrSetList.Count() );
1075 							}
1076 							pOld = 0;	// pOld nicht loeschen
1077 							break;		// das wars !!
1078 						}
1079 					}
1080 				}
1081 
1082 				pOld->pEndNd = pInsPos->MakeNodeIdx();
1083 				pOld->nEndCnt = pInsPos->GetCntIdx();
1084 
1085 #if 0
1086 				if( IsChkStyleAttr() )
1087 					_ClearStyleAttr( *pOld );
1088 #else
1089                 /*
1090                 #i21422#
1091                 If the parent (pAkt) sets something e.g. , and the child (pOld)
1092                 unsets it and the style both are based on has it unset then
1093                 clearing the pOld by looking at the style is clearly a disaster
1094                 as the text ends up with pAkts bold and not pOlds no bold, this
1095                 should be rethought out. For the moment its safest to just do
1096                 the clean if we have no parent, all we suffer is too many
1097                 redundant properties.
1098                 */
1099                 if (IsChkStyleAttr() && !pAkt)
1100 					_ClearStyleAttr( *pOld );
1101 #endif
1102 
1103 				if( pAkt )
1104 				{
1105 					pAkt->Add( pOld );
1106 					// split up and create new entry, because it make no sense
1107 					// to create a "so long" depend list. Bug 95010
1108 					if( bCrsrBack && 50 < pAkt->pChildList->Count() )
1109 					{
1110 						// am Absatzanfang ? eine Position zurueck
1111 						MovePos( sal_True );
1112 						bCrsrBack = sal_False;
1113 
1114 						// eine neue Gruppe aufmachen
1115 						SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
1116 												*pAkt, *pInsPos, sal_True );
1117 						pNew->SetRTFDefaults( GetRTFDefaults() );
1118 
1119 						// alle bis hierher gueltigen Attribute "setzen"
1120 						AttrGroupEnd();
1121                         pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();  // can be changed after AttrGroupEnd!
1122 						pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
1123 						aAttrStack.push_back( pNew );
1124 						pAkt = pNew;
1125 					}
1126 				}
1127 				else
1128 					// letzter vom Stack, also zwischenspeichern, bis der
1129 					// naechste Text eingelesen wurde. (keine Attribute
1130 					// aufspannen!!)
1131 					aAttrSetList.Insert( pOld, aAttrSetList.Count() );
1132 
1133 				pOld = 0;
1134 			}
1135 
1136 			if( bCrsrBack )
1137 				// am Absatzanfang ? eine Position zurueck
1138 				MovePos( sal_True );
1139 
1140 		} while( sal_False );
1141 
1142 		if( pOld )
1143 			delete pOld;
1144 
1145 		bNewGroup = sal_False;
1146 	}
1147 }
1148 
1149 void SvxRTFParser::SetAllAttrOfStk()		// end all Attr. and set it into doc
1150 {
1151 	// repeat until all attributes will be taken from stack
1152 	while( !aAttrStack.empty() )
1153 		AttrGroupEnd();
1154 
1155 	for( sal_uInt16 n = aAttrSetList.Count(); n; )
1156 	{
1157 		SvxRTFItemStackType* pStkSet = aAttrSetList[--n];
1158 		SetAttrSet( *pStkSet );
1159 		aAttrSetList.DeleteAndDestroy( n );
1160 	}
1161 }
1162 
1163 // setzt alle Attribute, die unterschiedlich zum aktuellen sind
1164 void SvxRTFParser::SetAttrSet( SvxRTFItemStackType &rSet )
1165 {
1166 	// wurde DefTab nie eingelesen? dann setze auf default
1167 	if( !bIsSetDfltTab )
1168 		SetDefault( RTF_DEFTAB, 720 );
1169 
1170 	if( rSet.pChildList )
1171 		rSet.Compress( *this );
1172 	if( rSet.aAttrSet.Count() || rSet.nStyleNo )
1173 		SetAttrInDoc( rSet );
1174 
1175 	// dann mal alle Childs abarbeiten
1176 	if( rSet.pChildList )
1177 		for( sal_uInt16 n = 0; n < rSet.pChildList->Count(); ++n )
1178 			SetAttrSet( *(*rSet.pChildList)[ n ] );
1179 }
1180 
1181 	// Is text wasn't inserted? (Get SttPos from the top of stack!)
1182 int	SvxRTFParser::IsAttrSttPos()
1183 {
1184     SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
1185 	return !pAkt || (pAkt->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
1186 		pAkt->nSttCnt == pInsPos->GetCntIdx());
1187 }
1188 
1189 
1190 void SvxRTFParser::SetAttrInDoc( SvxRTFItemStackType & )
1191 {
1192 }
1193 
1194 #ifdef USED
1195 void SvxRTFParser::SaveState( int nToken )
1196 {
1197 	SvRTFParser::SaveState( nToken );
1198 }
1199 
1200 void SvxRTFParser::RestoreState()
1201 {
1202 	SvRTFParser::RestoreState();
1203 }
1204 #endif
1205 
1206 void SvxRTFParser::BuildWhichTbl()
1207 {
1208 	if( aWhichMap.Count() )
1209 		aWhichMap.Remove( 0, aWhichMap.Count() );
1210 	aWhichMap.Insert( (sal_uInt16)0, (sal_uInt16)0 );
1211 
1212 	// Aufbau einer Which-Map 'rWhichMap' aus einem Array von
1213 	// 'pWhichIds' von Which-Ids. Es hat die Lange 'nWhichIds'.
1214 	// Die Which-Map wird nicht geloescht.
1215 	SvParser::BuildWhichTbl( aWhichMap, (sal_uInt16*)aPardMap.GetData(), aPardMap.Count() );
1216 	SvParser::BuildWhichTbl( aWhichMap, (sal_uInt16*)aPlainMap.GetData(), aPlainMap.Count() );
1217 }
1218 
1219 const SfxItemSet& SvxRTFParser::GetRTFDefaults()
1220 {
1221 	if( !pRTFDefaults )
1222 	{
1223 		pRTFDefaults = new SfxItemSet( *pAttrPool, aWhichMap.GetData() );
1224 		sal_uInt16 nId;
1225 		if( 0 != ( nId = ((RTFPardAttrMapIds*)aPardMap.GetData())->nScriptSpace ))
1226 		{
1227 			SvxScriptSpaceItem aItem( sal_False, nId );
1228 			if( bNewDoc )
1229 				pAttrPool->SetPoolDefaultItem( aItem );
1230 			else
1231 				pRTFDefaults->Put( aItem );
1232 		}
1233 	}
1234 	return *pRTFDefaults;
1235 }
1236 
1237 /**/
1238 
1239 SvxRTFStyleType::SvxRTFStyleType( SfxItemPool& rPool, const sal_uInt16* pWhichRange )
1240 	: aAttrSet( rPool, pWhichRange )
1241 {
1242 	nOutlineNo = sal_uInt8(-1);			// nicht gesetzt
1243 	nBasedOn = 0;
1244 	bBasedOnIsSet = sal_False;          //$flr #117411#
1245 	nNext = 0;
1246 	bIsCharFmt = sal_False;
1247 }
1248 
1249 
1250 SvxRTFItemStackType::SvxRTFItemStackType(
1251 		SfxItemPool& rPool, const sal_uInt16* pWhichRange,
1252 		const SvxPosition& rPos )
1253 	: aAttrSet( rPool, pWhichRange ),
1254 	pChildList( 0 ),
1255 	nStyleNo( 0 )
1256 {
1257 	pSttNd = rPos.MakeNodeIdx();
1258 	nSttCnt = rPos.GetCntIdx();
1259 	pEndNd = pSttNd;
1260 	nEndCnt = nSttCnt;
1261 }
1262 
1263 SvxRTFItemStackType::SvxRTFItemStackType(
1264 		const SvxRTFItemStackType& rCpy,
1265 		const SvxPosition& rPos,
1266 		int bCopyAttr )
1267 	: aAttrSet( *rCpy.aAttrSet.GetPool(), rCpy.aAttrSet.GetRanges() ),
1268 	pChildList( 0 ),
1269 	nStyleNo( rCpy.nStyleNo )
1270 {
1271 	pSttNd = rPos.MakeNodeIdx();
1272 	nSttCnt = rPos.GetCntIdx();
1273 	pEndNd = pSttNd;
1274 	nEndCnt = nSttCnt;
1275 
1276 	aAttrSet.SetParent( &rCpy.aAttrSet );
1277 	if( bCopyAttr )
1278 		aAttrSet.Put( rCpy.aAttrSet );
1279 }
1280 
1281 SvxRTFItemStackType::~SvxRTFItemStackType()
1282 {
1283 	if( pChildList )
1284 		delete pChildList;
1285 	if( pSttNd != pEndNd )
1286 		delete pEndNd;
1287 	delete pSttNd;
1288 }
1289 
1290 void SvxRTFItemStackType::Add( SvxRTFItemStackType* pIns )
1291 {
1292 	if( !pChildList )
1293 		 pChildList = new SvxRTFItemStackList( 4, 16 );
1294 	pChildList->Insert( pIns, pChildList->Count() );
1295 }
1296 
1297 #if 0
1298 //cmc: This is the original. nEndCnt is redundantly assigned to itself, and
1299 //pEndNd can leak if not equal to pSttNd.
1300 void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos )
1301 {
1302 	delete pSttNd;
1303 	pSttNd = rPos.MakeNodeIdx();
1304 	nSttCnt = rPos.GetCntIdx();
1305 	pEndNd = pSttNd;
1306 	nEndCnt = nEndCnt;
1307 }
1308 #else
1309 void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos )
1310 {
1311     if (pSttNd != pEndNd)
1312         delete pEndNd;
1313 	delete pSttNd;
1314 	pSttNd = rPos.MakeNodeIdx();
1315 	pEndNd = pSttNd;
1316 	nSttCnt = rPos.GetCntIdx();
1317 }
1318 #endif
1319 
1320 void SvxRTFItemStackType::MoveFullNode(const SvxNodeIdx &rOldNode,
1321     const SvxNodeIdx &rNewNode)
1322 {
1323     bool bSameEndAsStart = (pSttNd == pEndNd) ? true : false;
1324 
1325     if (GetSttNodeIdx() == rOldNode.GetIdx())
1326     {
1327         delete pSttNd;
1328         pSttNd = rNewNode.Clone();
1329         if (bSameEndAsStart)
1330             pEndNd = pSttNd;
1331     }
1332 
1333     if (!bSameEndAsStart && GetEndNodeIdx() == rOldNode.GetIdx())
1334     {
1335         delete pEndNd;
1336         pEndNd = rNewNode.Clone();
1337     }
1338 
1339     //And the same for all the children
1340     sal_uInt16 nCount = pChildList ? pChildList->Count() : 0;
1341     for (sal_uInt16 i = 0; i < nCount; ++i)
1342     {
1343         SvxRTFItemStackType* pStk = (*pChildList)[i];
1344         pStk->MoveFullNode(rOldNode, rNewNode);
1345     }
1346 }
1347 
1348 bool SvxRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &) const
1349 {
1350     return false;
1351 }
1352 
1353 void SvxRTFItemStackType::Compress( const SvxRTFParser& rParser )
1354 {
1355 	DBG_ASSERT( pChildList, "es gibt keine ChildListe" );
1356 
1357 	sal_uInt16 n;
1358 	SvxRTFItemStackType* pTmp = (*pChildList)[0];
1359 
1360 	if( !pTmp->aAttrSet.Count() ||
1361 		pSttNd->GetIdx() != pTmp->pSttNd->GetIdx() ||
1362 		nSttCnt != pTmp->nSttCnt )
1363 		return;
1364 
1365 	SvxNodeIdx* pLastNd = pTmp->pEndNd;
1366 	xub_StrLen nLastCnt = pTmp->nEndCnt;
1367 
1368 	SfxItemSet aMrgSet( pTmp->aAttrSet );
1369 	for( n = 1; n < pChildList->Count(); ++n )
1370 	{
1371 		pTmp = (*pChildList)[n];
1372 		if( pTmp->pChildList )
1373 			pTmp->Compress( rParser );
1374 
1375 		if( !pTmp->nSttCnt
1376 			? (pLastNd->GetIdx()+1 != pTmp->pSttNd->GetIdx() ||
1377 			   !rParser.IsEndPara( pLastNd, nLastCnt ) )
1378 			: ( pTmp->nSttCnt != nLastCnt ||
1379 				pLastNd->GetIdx() != pTmp->pSttNd->GetIdx() ))
1380 		{
1381 			while( ++n < pChildList->Count() )
1382 				if( (pTmp = (*pChildList)[n])->pChildList )
1383 					pTmp->Compress( rParser );
1384 			return;
1385 		}
1386 
1387         if (rParser.UncompressableStackEntry(*pTmp))
1388             return;
1389 
1390 		if( n )
1391 		{
1392 			// suche alle, die ueber den gesamten Bereich gesetzt sind
1393 			SfxItemIter aIter( aMrgSet );
1394 			const SfxPoolItem* pItem;
1395 			do {
1396 				sal_uInt16 nWhich = aIter.GetCurItem()->Which();
1397 				if( SFX_ITEM_SET != pTmp->aAttrSet.GetItemState( nWhich,
1398 					  sal_False, &pItem ) || *pItem != *aIter.GetCurItem() )
1399 					aMrgSet.ClearItem( nWhich );
1400 
1401 				if( aIter.IsAtEnd() )
1402 					break;
1403 				aIter.NextItem();
1404 			} while( sal_True );
1405 
1406 			if( !aMrgSet.Count() )
1407 				return;
1408 		}
1409 
1410 		pLastNd = pTmp->pEndNd;
1411 		nLastCnt = pTmp->nEndCnt;
1412 	}
1413 
1414 	if( pEndNd->GetIdx() != pLastNd->GetIdx() || nEndCnt != nLastCnt )
1415 		return;
1416 
1417 	// es kann zusammengefasst werden
1418 	aAttrSet.Put( aMrgSet );
1419 
1420 	for( n = 0; n < pChildList->Count(); ++n )
1421 	{
1422 		pTmp = (*pChildList)[n];
1423 		pTmp->aAttrSet.Differentiate( aMrgSet );
1424 
1425 		if( !pTmp->pChildList && !pTmp->aAttrSet.Count() && !pTmp->nStyleNo )
1426 		{
1427 			pChildList->Remove( n );
1428 			delete pTmp;
1429 			--n;
1430 			continue;
1431 		}
1432 	}
1433 	if( !pChildList->Count() )
1434 	{
1435 		delete pChildList;
1436 		pChildList = 0;
1437 	}
1438 }
1439 void SvxRTFItemStackType::SetRTFDefaults( const SfxItemSet& rDefaults )
1440 {
1441 	if( rDefaults.Count() )
1442 	{
1443 		SfxItemIter aIter( rDefaults );
1444 		do {
1445 			sal_uInt16 nWhich = aIter.GetCurItem()->Which();
1446 			if( SFX_ITEM_SET != aAttrSet.GetItemState( nWhich, sal_False ))
1447 				aAttrSet.Put( *aIter.GetCurItem() );
1448 
1449 			if( aIter.IsAtEnd() )
1450 				break;
1451 			aIter.NextItem();
1452 		} while( sal_True );
1453 	}
1454 }
1455 
1456 /**/
1457 
1458 RTFPlainAttrMapIds::RTFPlainAttrMapIds( const SfxItemPool& rPool )
1459 {
1460 	nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, sal_False );
1461 	nBgColor = rPool.GetTrueWhich( SID_ATTR_BRUSH_CHAR, sal_False );
1462 	nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, sal_False );
1463 	nContour = rPool.GetTrueWhich( SID_ATTR_CHAR_CONTOUR, sal_False );
1464 	nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, sal_False );
1465 	nEscapement = rPool.GetTrueWhich( SID_ATTR_CHAR_ESCAPEMENT, sal_False );
1466 	nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, sal_False );
1467 	nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, sal_False );
1468 	nKering = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, sal_False );
1469 	nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, sal_False );
1470 	nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, sal_False );
1471 	nShadowed = rPool.GetTrueWhich( SID_ATTR_CHAR_SHADOWED, sal_False );
1472 	nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, sal_False );
1473 	nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, sal_False );
1474 	nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, sal_False );
1475 	nWordlineMode = rPool.GetTrueWhich( SID_ATTR_CHAR_WORDLINEMODE, sal_False );
1476 	nAutoKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_AUTOKERN, sal_False );
1477 
1478 	nCJKFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, sal_False );
1479 	nCJKFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, sal_False );
1480 	nCJKLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, sal_False );
1481 	nCJKPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, sal_False );
1482 	nCJKWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, sal_False );
1483 	nCTLFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, sal_False );
1484 	nCTLFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, sal_False );
1485 	nCTLLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, sal_False );
1486 	nCTLPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, sal_False );
1487 	nCTLWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, sal_False );
1488 	nEmphasis = rPool.GetTrueWhich( SID_ATTR_CHAR_EMPHASISMARK, sal_False );
1489 	nTwoLines = rPool.GetTrueWhich( SID_ATTR_CHAR_TWO_LINES, sal_False );
1490 	nRuby = 0; //rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_RUBY, sal_False );
1491 	nCharScaleX = rPool.GetTrueWhich( SID_ATTR_CHAR_SCALEWIDTH, sal_False );
1492 	nHorzVert = rPool.GetTrueWhich( SID_ATTR_CHAR_ROTATED, sal_False );
1493 	nRelief = rPool.GetTrueWhich( SID_ATTR_CHAR_RELIEF, sal_False );
1494 	nHidden = rPool.GetTrueWhich( SID_ATTR_CHAR_HIDDEN, sal_False );
1495 }
1496 
1497 RTFPardAttrMapIds ::RTFPardAttrMapIds ( const SfxItemPool& rPool )
1498 {
1499 	nLinespacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, sal_False );
1500 	nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, sal_False );
1501 	nTabStop = rPool.GetTrueWhich( SID_ATTR_TABSTOP, sal_False );
1502 	nHyphenzone = rPool.GetTrueWhich( SID_ATTR_PARA_HYPHENZONE, sal_False );
1503 	nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, sal_False );
1504 	nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, sal_False );
1505 	nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, sal_False );
1506 	nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, sal_False );
1507 	nShadow = rPool.GetTrueWhich( SID_ATTR_BORDER_SHADOW, sal_False );
1508 	nOutlineLvl = rPool.GetTrueWhich( SID_ATTR_PARA_OUTLLEVEL, sal_False );
1509 	nSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, sal_False );
1510 	nKeep = rPool.GetTrueWhich( SID_ATTR_PARA_KEEP, sal_False );
1511 	nFontAlign = rPool.GetTrueWhich( SID_PARA_VERTALIGN, sal_False );
1512 	nScriptSpace = rPool.GetTrueWhich( SID_ATTR_PARA_SCRIPTSPACE, sal_False );
1513 	nHangPunct = rPool.GetTrueWhich( SID_ATTR_PARA_HANGPUNCTUATION, sal_False );
1514 	nForbRule = rPool.GetTrueWhich( SID_ATTR_PARA_FORBIDDEN_RULES, sal_False );
1515     nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, sal_False );
1516 }
1517 
1518 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
1519