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