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