Update ooo320-m1
[ooovba.git] / svx / source / svrtf / svxrtf.cxx
blob8808a1dfd9b490b29222537b44ae3782fbdf410a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svxrtf.cxx,v $
10 * $Revision: 1.34.212.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
37 #include <ctype.h>
38 #include <tools/datetime.hxx>
39 #include <rtl/tencinfo.h>
40 #include <svtools/itemiter.hxx>
41 #include <svtools/whiter.hxx>
42 #include <svtools/rtftoken.h>
43 #include <svtools/itempool.hxx>
45 #include <comphelper/string.hxx>
47 #include <com/sun/star/lang/Locale.hpp>
48 #include <svx/scriptspaceitem.hxx>
49 #include "fontitem.hxx"
50 #include <svx/colritem.hxx>
51 #include "svxrtf.hxx"
52 #include <svx/svxids.hrc>
53 #include <vcl/svapp.hxx>
55 #include <com/sun/star/document/XDocumentProperties.hpp>
58 using namespace ::com::sun::star;
61 SV_IMPL_PTRARR( SvxRTFColorTbl, ColorPtr )
62 SV_IMPL_PTRARR( SvxRTFItemStackList, SvxRTFItemStackType* )
64 CharSet lcl_GetDefaultTextEncodingForRTF()
67 ::com::sun::star::lang::Locale aLocale;
68 ::rtl::OUString aLangString;
70 aLocale = Application::GetSettings().GetLocale();
71 aLangString = aLocale.Language;
73 if ( aLangString.equals( ::rtl::OUString::createFromAscii( "ru" ) )
74 || aLangString.equals( ::rtl::OUString::createFromAscii( "uk" ) ) )
75 return RTL_TEXTENCODING_MS_1251;
76 if ( aLangString.equals( ::rtl::OUString::createFromAscii( "tr" ) ) )
77 return RTL_TEXTENCODING_MS_1254;
78 else
79 return RTL_TEXTENCODING_MS_1252;
82 // -------------- Methoden --------------------
84 SvxRTFParser::SvxRTFParser( SfxItemPool& rPool, SvStream& rIn,
85 uno::Reference<document::XDocumentProperties> i_xDocProps,
86 int bReadNewDoc )
87 : SvRTFParser( rIn, 5 ),
88 rStrm(rIn),
89 aColorTbl( 16, 4 ),
90 aFontTbl( 16, 4 ),
91 pInsPos( 0 ),
92 pAttrPool( &rPool ),
93 m_xDocProps( i_xDocProps ),
94 pRTFDefaults( 0 ),
95 nVersionNo( 0 )
97 bNewDoc = bReadNewDoc;
99 bChkStyleAttr = bCalcValue = bReadDocInfo = bIsInReadStyleTab = FALSE;
100 bIsLeftToRightDef = TRUE;
103 RTFPlainAttrMapIds aTmp( rPool );
104 aPlainMap.Insert( (USHORT*)&aTmp,
105 sizeof( RTFPlainAttrMapIds ) / sizeof(USHORT), 0 );
108 RTFPardAttrMapIds aTmp( rPool );
109 aPardMap.Insert( (USHORT*)&aTmp,
110 sizeof( RTFPardAttrMapIds ) / sizeof(USHORT), 0 );
112 pDfltFont = new Font;
113 pDfltColor = new Color;
116 void SvxRTFParser::EnterEnvironment()
120 void SvxRTFParser::LeaveEnvironment()
124 void SvxRTFParser::ResetPard()
128 SvxRTFParser::~SvxRTFParser()
130 if( aColorTbl.Count() )
131 ClearColorTbl();
132 if( aFontTbl.Count() )
133 ClearFontTbl();
134 if( aStyleTbl.Count() )
135 ClearStyleTbl();
136 if( aAttrStack.Count() )
137 ClearAttrStack();
139 delete pRTFDefaults;
141 delete pInsPos;
142 delete pDfltFont;
143 delete pDfltColor;
146 void SvxRTFParser::SetInsPos( const SvxPosition& rNew )
148 if( pInsPos )
149 delete pInsPos;
150 pInsPos = rNew.Clone();
153 SvParserState SvxRTFParser::CallParser()
155 DBG_ASSERT( pInsPos, "keine Einfuegeposition" );
157 if( !pInsPos )
158 return SVPAR_ERROR;
160 if( aColorTbl.Count() )
161 ClearColorTbl();
162 if( aFontTbl.Count() )
163 ClearFontTbl();
164 if( aStyleTbl.Count() )
165 ClearStyleTbl();
166 if( aAttrStack.Count() )
167 ClearAttrStack();
169 bIsSetDfltTab = FALSE;
170 bNewGroup = FALSE;
171 nDfltFont = 0;
173 sBaseURL.Erase();
175 // erzeuge aus den gesetzten WhichIds die richtige WhichId-Tabelle.
176 BuildWhichTbl();
178 return SvRTFParser::CallParser();
181 void SvxRTFParser::Continue( int nToken )
183 SvRTFParser::Continue( nToken );
185 if( SVPAR_PENDING != GetStatus() )
187 SetAllAttrOfStk();
188 #if 0
189 //Regardless of what "color 0" is, word defaults to auto as the default colour.
190 //e.g. see #i7713#
191 if( bNewDoc && ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nColor )
192 pAttrPool->SetPoolDefaultItem( SvxColorItem( GetColor( 0 ),
193 ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nColor ));
194 #endif
199 // wird fuer jedes Token gerufen, das in CallParser erkannt wird
200 void SvxRTFParser::NextToken( int nToken )
202 sal_Unicode cCh;
203 switch( nToken )
205 case RTF_COLORTBL: ReadColorTable(); break;
206 case RTF_FONTTBL: ReadFontTable(); break;
207 case RTF_STYLESHEET: ReadStyleTable(); break;
209 case RTF_DEFF:
210 if( bNewDoc )
212 if( aFontTbl.Count() )
213 // koennen wir sofort setzen
214 SetDefault( nToken, nTokenValue );
215 else
216 // wird nach einlesen der Fonttabelle gesetzt
217 nDfltFont = int(nTokenValue);
219 break;
221 case RTF_DEFTAB:
222 case RTF_DEFLANG:
223 if( bNewDoc )
224 SetDefault( nToken, nTokenValue );
225 break;
228 case RTF_PICT: ReadBitmapData(); break;
230 case RTF_LINE: cCh = '\n'; goto INSINGLECHAR;
231 case RTF_TAB: cCh = '\t'; goto INSINGLECHAR;
232 case RTF_SUBENTRYINDEX: cCh = ':'; goto INSINGLECHAR;
234 case RTF_EMDASH: cCh = 151; goto INSINGLECHAR;
235 case RTF_ENDASH: cCh = 150; goto INSINGLECHAR;
236 case RTF_BULLET: cCh = 149; goto INSINGLECHAR;
237 case RTF_LQUOTE: cCh = 145; goto INSINGLECHAR;
238 case RTF_RQUOTE: cCh = 146; goto INSINGLECHAR;
239 case RTF_LDBLQUOTE: cCh = 147; goto INSINGLECHAR;
240 case RTF_RDBLQUOTE: cCh = 148; goto INSINGLECHAR;
241 INSINGLECHAR:
242 aToken = ByteString::ConvertToUnicode( (sal_Char)cCh,
243 RTL_TEXTENCODING_MS_1252 );
245 // kein Break, aToken wird als Text gesetzt
246 case RTF_TEXTTOKEN:
248 InsertText();
249 // alle angesammelten Attribute setzen
250 for( USHORT n = aAttrSetList.Count(); n; )
252 SvxRTFItemStackType* pStkSet = aAttrSetList[--n];
253 SetAttrSet( *pStkSet );
254 aAttrSetList.DeleteAndDestroy( n );
257 break;
260 case RTF_PAR:
261 InsertPara();
262 break;
263 case '{':
264 if (bNewGroup) // Verschachtelung !!
265 _GetAttrSet();
266 EnterEnvironment();
267 bNewGroup = true;
268 break;
269 case '}':
270 if( !bNewGroup ) // leere Gruppe ??
271 AttrGroupEnd();
272 LeaveEnvironment();
273 bNewGroup = false;
274 break;
275 case RTF_INFO:
276 #ifndef SVX_LIGHT
277 if (bReadDocInfo && bNewDoc && m_xDocProps.is())
278 ReadInfo();
279 else
280 #endif
281 SkipGroup();
282 break;
284 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
285 // erstmal gesamt ueberlesen (muessen alle in einer Gruppe stehen !!)
286 // Koennen auch ohne dem IGNORE-Flag im RTF-File auftreten; alle Gruppen
287 // mit IGNORE-Flag werden im default-Zweig ueberlesen.
289 case RTF_SWG_PRTDATA:
290 case RTF_FIELD:
291 case RTF_ATNID:
292 case RTF_ANNOTATION:
294 case RTF_BKMKSTART:
295 case RTF_BKMKEND:
296 case RTF_BKMK_KEY:
297 case RTF_XE:
298 case RTF_TC:
299 case RTF_NEXTFILE:
300 case RTF_TEMPLATE:
301 #if 0
302 //disabled for #i19718#
303 case RTF_SHPRSLT: // RTF_SHP fehlt noch !!
304 #endif
305 SkipGroup();
306 break;
307 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
309 case RTF_PGDSCNO:
310 case RTF_PGBRK:
311 case RTF_SHADOW:
312 if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
313 break;
314 nToken = SkipToken( -1 );
315 if( '{' == GetStackPtr( -1 )->nTokenId )
316 nToken = SkipToken( -1 );
318 ReadAttr( nToken, &GetAttrSet() );
319 break;
321 default:
322 switch( nToken & ~(0xff | RTF_SWGDEFS) )
324 case RTF_PARFMT: // hier gibts keine Swg-Defines
325 ReadAttr( nToken, &GetAttrSet() );
326 break;
328 case RTF_CHRFMT:
329 case RTF_BRDRDEF:
330 case RTF_TABSTOPDEF:
332 if( RTF_SWGDEFS & nToken)
334 if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
335 break;
336 nToken = SkipToken( -1 );
337 if( '{' == GetStackPtr( -1 )->nTokenId )
339 nToken = SkipToken( -1 );
342 ReadAttr( nToken, &GetAttrSet() );
343 break;
344 default:
346 if( /*( '{' == GetStackPtr( -1 )->nTokenId ) ||*/
347 ( RTF_IGNOREFLAG == GetStackPtr( -1 )->nTokenId &&
348 '{' == GetStackPtr( -2 )->nTokenId ) )
349 SkipGroup();
351 break;
353 break;
357 void SvxRTFParser::ReadStyleTable()
359 int nToken, bSaveChkStyleAttr = bChkStyleAttr;
360 short nStyleNo = 0;
361 int _nOpenBrakets = 1; // die erste wurde schon vorher erkannt !!
362 SvxRTFStyleType* pStyle = new SvxRTFStyleType( *pAttrPool, aWhichMap.GetData() );
363 pStyle->aAttrSet.Put( GetRTFDefaults() );
365 bIsInReadStyleTab = TRUE;
366 bChkStyleAttr = FALSE; // Attribute nicht gegen die Styles checken
368 while( _nOpenBrakets && IsParserWorking() )
370 switch( nToken = GetNextToken() )
372 case '}': if( --_nOpenBrakets && IsParserWorking() )
373 // Style konnte vollstaendig gelesen werden,
374 // also ist das noch ein stabiler Status
375 SaveState( RTF_STYLESHEET );
376 break;
377 case '{':
379 if( RTF_IGNOREFLAG != GetNextToken() )
380 nToken = SkipToken( -1 );
381 else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
382 RTF_PN != nToken )
383 nToken = SkipToken( -2 );
384 else
386 // gleich herausfiltern
387 ReadUnknownData();
388 nToken = GetNextToken();
389 if( '}' != nToken )
390 eState = SVPAR_ERROR;
391 break;
393 ++_nOpenBrakets;
395 break;
397 case RTF_SBASEDON: pStyle->nBasedOn = USHORT(nTokenValue); pStyle->bBasedOnIsSet=TRUE; break;
398 case RTF_SNEXT: pStyle->nNext = USHORT(nTokenValue); break;
399 case RTF_OUTLINELEVEL:
400 case RTF_SOUTLVL: pStyle->nOutlineNo = BYTE(nTokenValue); break;
401 case RTF_S: nStyleNo = (short)nTokenValue; break;
402 case RTF_CS: nStyleNo = (short)nTokenValue;
403 pStyle->bIsCharFmt = TRUE;
404 break;
406 case RTF_TEXTTOKEN:
408 pStyle->sName = DelCharAtEnd( aToken, ';' );
411 ??? soll man das umsetzen ???
412 if( !pStyle->sName.Len() )
413 pStyle->sName = "Standard";
415 // sollte die Nummer doppelt vergeben werden ?
416 if( aStyleTbl.Count() )
418 SvxRTFStyleType* pOldSt = aStyleTbl.Remove( nStyleNo );
419 if( pOldSt )
420 delete pOldSt;
422 // alle Daten vom Style vorhanden, also ab in die Tabelle
423 aStyleTbl.Insert( nStyleNo, pStyle );
424 pStyle = new SvxRTFStyleType( *pAttrPool, aWhichMap.GetData() );
425 pStyle->aAttrSet.Put( GetRTFDefaults() );
426 nStyleNo = 0;
428 break;
429 default:
430 switch( nToken & ~(0xff | RTF_SWGDEFS) )
432 case RTF_PARFMT: // hier gibts keine Swg-Defines
433 ReadAttr( nToken, &pStyle->aAttrSet );
434 break;
436 case RTF_CHRFMT:
437 case RTF_BRDRDEF:
438 case RTF_TABSTOPDEF:
440 if( RTF_SWGDEFS & nToken)
442 if( RTF_IGNOREFLAG != GetStackPtr( -1 )->nTokenId )
443 break;
444 nToken = SkipToken( -1 );
445 if( '{' == GetStackPtr( -1 )->nTokenId )
447 nToken = SkipToken( -1 );
448 #if 0
449 --_nOpenBrakets; // korrigieren!!
450 #endif
453 ReadAttr( nToken, &pStyle->aAttrSet );
454 break;
456 break;
459 delete pStyle; // loesche das letze Style
460 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
462 // Flag wieder auf alten Zustand
463 bChkStyleAttr = bSaveChkStyleAttr;
464 bIsInReadStyleTab = FALSE;
467 void SvxRTFParser::ReadColorTable()
469 int nToken;
470 BYTE nRed = 0xff, nGreen = 0xff, nBlue = 0xff;
472 while( '}' != ( nToken = GetNextToken() ) && IsParserWorking() )
474 switch( nToken )
476 case RTF_RED: nRed = BYTE(nTokenValue); break;
477 case RTF_GREEN: nGreen = BYTE(nTokenValue); break;
478 case RTF_BLUE: nBlue = BYTE(nTokenValue); break;
480 case RTF_TEXTTOKEN: // oder sollte irgendein Unsin darumstehen?
481 if( 1 == aToken.Len()
482 ? aToken.GetChar( 0 ) != ';'
483 : STRING_NOTFOUND == aToken.Search( ';' ) )
484 break; // es muss zumindestens das ';' gefunden werden
486 // else kein break !!
488 case ';':
489 if( IsParserWorking() )
491 // eine Farbe ist Fertig, in die Tabelle eintragen
492 // versuche die Werte auf SV interne Namen zu mappen
493 ColorPtr pColor = new Color( nRed, nGreen, nBlue );
494 if( !aColorTbl.Count() &&
495 BYTE(-1) == nRed && BYTE(-1) == nGreen && BYTE(-1) == nBlue )
496 pColor->SetColor( COL_AUTO );
497 aColorTbl.Insert( pColor, aColorTbl.Count() );
498 nRed = 0, nGreen = 0, nBlue = 0;
500 // Color konnte vollstaendig gelesen werden,
501 // also ist das noch ein stabiler Status
502 SaveState( RTF_COLORTBL );
504 break;
507 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
510 void SvxRTFParser::ReadFontTable()
512 int nToken;
513 int _nOpenBrakets = 1; // die erste wurde schon vorher erkannt !!
514 Font* pFont = new Font();
515 short nFontNo(0), nInsFontNo (0);
516 String sAltNm, sFntNm;
517 BOOL bIsAltFntNm = FALSE, bCheckNewFont;
519 CharSet nSystemChar = lcl_GetDefaultTextEncodingForRTF();
520 pFont->SetCharSet( nSystemChar );
521 SetEncoding( nSystemChar );
523 while( _nOpenBrakets && IsParserWorking() )
525 bCheckNewFont = FALSE;
526 switch( ( nToken = GetNextToken() ))
528 case '}':
529 bIsAltFntNm = FALSE;
530 // Style konnte vollstaendig gelesen werden,
531 // also ist das noch ein stabiler Status
532 if( --_nOpenBrakets <= 1 && IsParserWorking() )
533 SaveState( RTF_FONTTBL );
534 bCheckNewFont = TRUE;
535 nInsFontNo = nFontNo;
536 break;
537 case '{':
538 if( RTF_IGNOREFLAG != GetNextToken() )
539 nToken = SkipToken( -1 );
540 // Unknown und alle bekannten nicht ausgewerteten Gruppen
541 // sofort ueberspringen
542 else if( RTF_UNKNOWNCONTROL != ( nToken = GetNextToken() ) &&
543 RTF_PANOSE != nToken && RTF_FNAME != nToken &&
544 RTF_FONTEMB != nToken && RTF_FONTFILE != nToken )
545 nToken = SkipToken( -2 );
546 else
548 // gleich herausfiltern
549 ReadUnknownData();
550 nToken = GetNextToken();
551 if( '}' != nToken )
552 eState = SVPAR_ERROR;
553 break;
555 ++_nOpenBrakets;
556 break;
557 case RTF_FROMAN:
558 pFont->SetFamily( FAMILY_ROMAN );
559 break;
560 case RTF_FSWISS:
561 pFont->SetFamily( FAMILY_SWISS );
562 break;
563 case RTF_FMODERN:
564 pFont->SetFamily( FAMILY_MODERN );
565 break;
566 case RTF_FSCRIPT:
567 pFont->SetFamily( FAMILY_SCRIPT );
568 break;
569 case RTF_FDECOR:
570 pFont->SetFamily( FAMILY_DECORATIVE );
571 break;
572 // bei technischen/symbolischen Font wird der CharSet ungeschaltet!!
573 case RTF_FTECH:
574 pFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
575 // deliberate fall through
576 case RTF_FNIL:
577 pFont->SetFamily( FAMILY_DONTKNOW );
578 break;
579 case RTF_FCHARSET:
580 if (-1 != nTokenValue)
582 CharSet nCharSet = rtl_getTextEncodingFromWindowsCharset(
583 (BYTE)nTokenValue);
584 pFont->SetCharSet(nCharSet);
585 //When we're in a font, the fontname is in the font
586 //charset, except for symbol fonts I believe
587 if (nCharSet == RTL_TEXTENCODING_SYMBOL)
588 nCharSet = RTL_TEXTENCODING_DONTKNOW;
589 SetEncoding(nCharSet);
591 break;
592 case RTF_FPRQ:
593 switch( nTokenValue )
595 case 1:
596 pFont->SetPitch( PITCH_FIXED );
597 break;
598 case 2:
599 pFont->SetPitch( PITCH_VARIABLE );
600 break;
602 break;
603 case RTF_F:
604 bCheckNewFont = TRUE;
605 nInsFontNo = nFontNo;
606 nFontNo = (short)nTokenValue;
607 break;
608 case RTF_FALT:
609 bIsAltFntNm = TRUE;
610 break;
611 case RTF_TEXTTOKEN:
612 DelCharAtEnd( aToken, ';' );
613 if ( aToken.Len() )
615 if( bIsAltFntNm )
616 sAltNm = aToken;
617 else
618 sFntNm = aToken;
620 break;
623 if( bCheckNewFont && 1 >= _nOpenBrakets && sFntNm.Len() ) // one font is ready
625 // alle Daten vom Font vorhanden, also ab in die Tabelle
626 if (sAltNm.Len())
627 (sFntNm += ';' ) += sAltNm;
629 pFont->SetName( sFntNm );
630 aFontTbl.Insert( nInsFontNo, pFont );
631 pFont = new Font();
632 pFont->SetCharSet( nSystemChar );
633 sAltNm.Erase();
634 sFntNm.Erase();
637 // den letzen muessen wir selbst loeschen
638 delete pFont;
639 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
641 // setze den default Font am Doc
642 if( bNewDoc && IsParserWorking() )
643 SetDefault( RTF_DEFF, nDfltFont );
646 void SvxRTFParser::ReadBitmapData()
648 SvRTFParser::ReadBitmapData();
651 void SvxRTFParser::ReadOLEData()
653 SvRTFParser::ReadOLEData();
656 String& SvxRTFParser::GetTextToEndGroup( String& rStr )
658 rStr.Erase( 0 );
659 int _nOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !!
661 while( _nOpenBrakets && IsParserWorking() )
663 switch( nToken = GetNextToken() )
665 case '}': --_nOpenBrakets; break;
666 case '{':
668 if( RTF_IGNOREFLAG != GetNextToken() )
669 nToken = SkipToken( -1 );
670 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
671 nToken = SkipToken( -2 );
672 else
674 // gleich herausfiltern
675 ReadUnknownData();
676 nToken = GetNextToken();
677 if( '}' != nToken )
678 eState = SVPAR_ERROR;
679 break;
681 ++_nOpenBrakets;
683 break;
685 case RTF_TEXTTOKEN:
686 rStr += aToken;
687 break;
690 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
691 return rStr;
694 util::DateTime SvxRTFParser::GetDateTimeStamp( )
696 util::DateTime aDT;
697 BOOL bWeiter = TRUE;
698 int nToken;
699 while( bWeiter && IsParserWorking() )
701 switch( nToken = GetNextToken() )
703 case RTF_YR: aDT.Year = (USHORT)nTokenValue; break;
704 case RTF_MO: aDT.Month = (USHORT)nTokenValue; break;
705 case RTF_DY: aDT.Day = (USHORT)nTokenValue; break;
706 case RTF_HR: aDT.Hours = (USHORT)nTokenValue; break;
707 case RTF_MIN: aDT.Minutes = (USHORT)nTokenValue; break;
708 default:
709 bWeiter = FALSE;
712 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
713 return aDT;
716 void SvxRTFParser::ReadInfo( const sal_Char* pChkForVerNo )
718 #ifndef SVX_LIGHT
719 int _nOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !!
720 DBG_ASSERT(m_xDocProps.is(),
721 "SvxRTFParser::ReadInfo: no DocumentProperties");
722 String sStr, sComment;
723 long nVersNo = 0;
725 while( _nOpenBrakets && IsParserWorking() )
727 switch( nToken = GetNextToken() )
729 case '}': --_nOpenBrakets; break;
730 case '{':
732 if( RTF_IGNOREFLAG != GetNextToken() )
733 nToken = SkipToken( -1 );
734 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
735 nToken = SkipToken( -2 );
736 else
738 // gleich herausfiltern
739 ReadUnknownData();
740 nToken = GetNextToken();
741 if( '}' != nToken )
742 eState = SVPAR_ERROR;
743 break;
745 ++_nOpenBrakets;
747 break;
749 case RTF_TITLE:
750 m_xDocProps->setTitle( GetTextToEndGroup( sStr ) );
751 break;
752 case RTF_SUBJECT:
753 m_xDocProps->setSubject( GetTextToEndGroup( sStr ) );
754 break;
755 case RTF_AUTHOR:
756 m_xDocProps->setAuthor( GetTextToEndGroup( sStr ) );
757 break;
758 case RTF_OPERATOR:
759 m_xDocProps->setModifiedBy( GetTextToEndGroup( sStr ) );
760 break;
761 case RTF_KEYWORDS:
763 ::rtl::OUString sTemp = GetTextToEndGroup( sStr );
764 m_xDocProps->setKeywords(
765 ::comphelper::string::convertCommaSeparated(sTemp) );
766 break;
768 case RTF_DOCCOMM:
769 m_xDocProps->setDescription( GetTextToEndGroup( sStr ) );
770 break;
772 case RTF_HLINKBASE:
773 sBaseURL = GetTextToEndGroup( sStr ) ;
774 break;
776 case RTF_CREATIM:
777 m_xDocProps->setCreationDate( GetDateTimeStamp() );
778 break;
780 case RTF_REVTIM:
781 m_xDocProps->setModificationDate( GetDateTimeStamp() );
782 break;
784 case RTF_PRINTIM:
785 m_xDocProps->setPrintDate( GetDateTimeStamp() );
786 break;
788 case RTF_COMMENT:
789 GetTextToEndGroup( sComment );
790 break;
792 case RTF_BUPTIM:
793 SkipGroup();
794 break;
796 case RTF_VERN:
797 nVersNo = nTokenValue;
798 break;
800 case RTF_EDMINS:
801 case RTF_ID:
802 case RTF_VERSION:
803 case RTF_NOFPAGES:
804 case RTF_NOFWORDS:
805 case RTF_NOFCHARS:
806 NextToken( nToken );
807 break;
809 // default:
813 if( pChkForVerNo &&
814 COMPARE_EQUAL == sComment.CompareToAscii( pChkForVerNo ))
815 nVersionNo = nVersNo;
817 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
818 #endif
822 void SvxRTFParser::ClearColorTbl()
824 aColorTbl.DeleteAndDestroy( 0, aColorTbl.Count() );
827 void SvxRTFParser::ClearFontTbl()
829 for( ULONG nCnt = aFontTbl.Count(); nCnt; )
830 delete aFontTbl.GetObject( --nCnt );
833 void SvxRTFParser::ClearStyleTbl()
835 for( ULONG nCnt = aStyleTbl.Count(); nCnt; )
836 delete aStyleTbl.GetObject( --nCnt );
839 void SvxRTFParser::ClearAttrStack()
841 SvxRTFItemStackType* pTmp;
842 for( ULONG nCnt = aAttrStack.Count(); nCnt; --nCnt )
844 pTmp = aAttrStack.Pop();
845 delete pTmp;
849 String& SvxRTFParser::DelCharAtEnd( String& rStr, const sal_Unicode cDel )
851 if( rStr.Len() && ' ' == rStr.GetChar( 0 ))
852 rStr.EraseLeadingChars();
853 if( rStr.Len() && ' ' == rStr.GetChar( rStr.Len()-1 ))
854 rStr.EraseTrailingChars();
855 if( rStr.Len() && cDel == rStr.GetChar( rStr.Len()-1 ))
856 rStr.Erase( rStr.Len()-1 );
857 return rStr;
861 const Font& SvxRTFParser::GetFont( USHORT nId )
863 const Font* pFont = aFontTbl.Get( nId );
864 if( !pFont )
866 const SvxFontItem& rDfltFont = (const SvxFontItem&)
867 pAttrPool->GetDefaultItem(
868 ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nFont );
869 pDfltFont->SetName( rDfltFont.GetStyleName() );
870 pDfltFont->SetFamily( rDfltFont.GetFamily() );
871 pFont = pDfltFont;
873 return *pFont;
876 SvxRTFItemStackType* SvxRTFParser::_GetAttrSet( int bCopyAttr )
878 SvxRTFItemStackType* pAkt = aAttrStack.Top();
879 SvxRTFItemStackType* pNew;
880 if( pAkt )
881 pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, bCopyAttr );
882 else
883 pNew = new SvxRTFItemStackType( *pAttrPool, aWhichMap.GetData(),
884 *pInsPos );
885 pNew->SetRTFDefaults( GetRTFDefaults() );
887 aAttrStack.Push( pNew );
888 bNewGroup = FALSE;
889 return pNew;
893 void SvxRTFParser::_ClearStyleAttr( SvxRTFItemStackType& rStkType )
895 // check attributes to the attributes of the stylesheet or to
896 // the default attrs of the document
897 SfxItemSet &rSet = rStkType.GetAttrSet();
898 const SfxItemPool& rPool = *rSet.GetPool();
899 const SfxPoolItem* pItem;
900 SfxWhichIter aIter( rSet );
902 SvxRTFStyleType* pStyle;
903 if( !IsChkStyleAttr() ||
904 !rStkType.GetAttrSet().Count() ||
905 0 == ( pStyle = aStyleTbl.Get( rStkType.nStyleNo ) ))
907 for( USHORT nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() )
909 if( SFX_WHICH_MAX > nWhich &&
910 SFX_ITEM_SET == rSet.GetItemState( nWhich, FALSE, &pItem ) &&
911 rPool.GetDefaultItem( nWhich ) == *pItem )
912 rSet.ClearItem( nWhich ); // loeschen
915 else
917 // alle Attribute, die schon vom Style definiert sind, aus dem
918 // akt. AttrSet entfernen
919 SfxItemSet &rStyleSet = pStyle->aAttrSet;
920 const SfxPoolItem* pSItem;
921 for( USHORT nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() )
923 if( SFX_ITEM_SET == rStyleSet.GetItemState( nWhich, TRUE, &pSItem ))
925 // JP 22.06.99: im Style und im Set gleich gesetzt -> loeschen
926 if( SFX_ITEM_SET == rSet.GetItemState( nWhich, FALSE, &pItem )
927 && *pItem == *pSItem )
928 rSet.ClearItem( nWhich ); // loeschen
930 // Bug 59571 - falls nicht im Style gesetzt und gleich mit
931 // dem PoolDefault -> auch dann loeschen
932 else if( SFX_WHICH_MAX > nWhich &&
933 SFX_ITEM_SET == rSet.GetItemState( nWhich, FALSE, &pItem ) &&
934 rPool.GetDefaultItem( nWhich ) == *pItem )
935 rSet.ClearItem( nWhich ); // loeschen
940 void SvxRTFParser::AttrGroupEnd() // den akt. Bearbeiten, vom Stack loeschen
942 if( aAttrStack.Count() )
944 SvxRTFItemStackType *pOld = aAttrStack.Pop();
945 SvxRTFItemStackType *pAkt = aAttrStack.Top();
947 do { // middle check loop
948 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
955 // setze nur die Attribute, die unterschiedlich zum Parent sind
956 if( pAkt && pOld->aAttrSet.Count() )
958 SfxItemIter aIter( pOld->aAttrSet );
959 const SfxPoolItem* pItem = aIter.GetCurItem(), *pGet;
960 while( TRUE )
962 if( SFX_ITEM_SET == pAkt->aAttrSet.GetItemState(
963 pItem->Which(), FALSE, &pGet ) &&
964 *pItem == *pGet )
965 pOld->aAttrSet.ClearItem( pItem->Which() );
967 if( aIter.IsAtEnd() )
968 break;
969 pItem = aIter.NextItem();
972 if( !pOld->aAttrSet.Count() && !pOld->pChildList &&
973 !pOld->nStyleNo )
974 break;
977 // setze alle Attribute, die von Start bis hier
978 // definiert sind.
979 int bCrsrBack = !pInsPos->GetCntIdx();
980 if( bCrsrBack )
982 // am Absatzanfang ? eine Position zurueck
983 ULONG nNd = pInsPos->GetNodeIdx();
984 MovePos( FALSE );
985 // if can not move backward then later dont move forward !
986 bCrsrBack = nNd != pInsPos->GetNodeIdx();
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 - dont test for empty paragraph or any range
995 && ( nOldSttNdIdx != pInsPos->GetNodeIdx() ||
996 pOld->nSttCnt != pInsPos->GetCntIdx() ||
997 !pOld->nSttCnt )
998 #endif
1001 if( !bCrsrBack )
1003 // alle pard-Attribute gelten nur bis zum vorherigen
1004 // Absatz !!
1005 if( nOldSttNdIdx == pInsPos->GetNodeIdx() )
1007 #if 0
1008 //BUG 68555 - dont 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 )
1015 pOld->nStyleNo = 0;
1016 for( USHORT n = 0; n < aPardMap.Count() &&
1017 pOld->aAttrSet.Count(); ++n )
1018 if( aPardMap[n] )
1019 pOld->aAttrSet.ClearItem( aPardMap[n] );
1021 if( !pOld->aAttrSet.Count() && !pOld->pChildList &&
1022 !pOld->nStyleNo )
1023 break; // auch dieser verlaesst uns jetzt
1025 #endif
1027 else
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, TRUE );
1035 pNew->aAttrSet.SetParent( pOld->aAttrSet.GetParent() );
1037 // loesche aus pNew alle Absatz Attribute
1038 for( USHORT n = 0; n < aPardMap.Count() &&
1039 pNew->aAttrSet.Count(); ++n )
1040 if( aPardMap[n] )
1041 pNew->aAttrSet.ClearItem( aPardMap[n] );
1042 pNew->SetRTFDefaults( GetRTFDefaults() );
1044 // gab es ueberhaupt welche ?
1045 if( pNew->aAttrSet.Count() == pOld->aAttrSet.Count() )
1046 delete pNew; // das wars dann
1047 else
1049 pNew->nStyleNo = 0;
1051 // spanne jetzt den richtigen Bereich auf
1052 // pNew von alter
1053 SetEndPrevPara( pOld->pEndNd, pOld->nEndCnt );
1054 pNew->nSttCnt = 0;
1056 if( IsChkStyleAttr() )
1058 _ClearStyleAttr( *pOld );
1059 _ClearStyleAttr( *pNew ); //#i10381#, methinks.
1062 if( pAkt )
1064 pAkt->Add( pOld );
1065 pAkt->Add( pNew );
1067 else
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() );
1075 pOld = 0; // pOld nicht loeschen
1076 break; // das wars !!
1081 pOld->pEndNd = pInsPos->MakeNodeIdx();
1082 pOld->nEndCnt = pInsPos->GetCntIdx();
1084 #if 0
1085 if( IsChkStyleAttr() )
1086 _ClearStyleAttr( *pOld );
1087 #else
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.
1098 if (IsChkStyleAttr() && !pAkt)
1099 _ClearStyleAttr( *pOld );
1100 #endif
1102 if( pAkt )
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() )
1109 // am Absatzanfang ? eine Position zurueck
1110 MovePos( TRUE );
1111 bCrsrBack = FALSE;
1113 // eine neue Gruppe aufmachen
1114 SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
1115 *pAkt, *pInsPos, TRUE );
1116 pNew->SetRTFDefaults( GetRTFDefaults() );
1118 // alle bis hierher gueltigen Attribute "setzen"
1119 AttrGroupEnd();
1120 pAkt = aAttrStack.Top(); // can be changed after AttrGroupEnd!
1121 pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
1122 aAttrStack.Push( pNew );
1123 pAkt = pNew;
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() );
1132 pOld = 0;
1135 if( bCrsrBack )
1136 // am Absatzanfang ? eine Position zurueck
1137 MovePos( TRUE );
1139 } while( FALSE );
1141 if( pOld )
1142 delete pOld;
1144 bNewGroup = FALSE;
1148 void SvxRTFParser::SetAllAttrOfStk() // end all Attr. and set it into doc
1150 // noch alle Attrbute vom Stack holen !!
1151 while( aAttrStack.Count() )
1152 AttrGroupEnd();
1154 for( USHORT n = aAttrSetList.Count(); n; )
1156 SvxRTFItemStackType* pStkSet = aAttrSetList[--n];
1157 SetAttrSet( *pStkSet );
1158 aAttrSetList.DeleteAndDestroy( n );
1162 // setzt alle Attribute, die unterschiedlich zum aktuellen sind
1163 void SvxRTFParser::SetAttrSet( SvxRTFItemStackType &rSet )
1165 // wurde DefTab nie eingelesen? dann setze auf default
1166 if( !bIsSetDfltTab )
1167 SetDefault( RTF_DEFTAB, 720 );
1169 if( rSet.pChildList )
1170 rSet.Compress( *this );
1171 if( rSet.aAttrSet.Count() || rSet.nStyleNo )
1172 SetAttrInDoc( rSet );
1174 // dann mal alle Childs abarbeiten
1175 if( rSet.pChildList )
1176 for( USHORT n = 0; n < rSet.pChildList->Count(); ++n )
1177 SetAttrSet( *(*rSet.pChildList)[ n ] );
1180 // wurde noch kein Text eingefuegt ? (SttPos vom obersten StackEintrag!)
1181 int SvxRTFParser::IsAttrSttPos()
1183 SvxRTFItemStackType* pAkt = aAttrStack.Top();
1184 return !pAkt || (pAkt->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
1185 pAkt->nSttCnt == pInsPos->GetCntIdx());
1189 void SvxRTFParser::SetAttrInDoc( SvxRTFItemStackType & )
1193 #ifdef USED
1194 void SvxRTFParser::SaveState( int nToken )
1196 SvRTFParser::SaveState( nToken );
1199 void SvxRTFParser::RestoreState()
1201 SvRTFParser::RestoreState();
1203 #endif
1205 void SvxRTFParser::BuildWhichTbl()
1207 if( aWhichMap.Count() )
1208 aWhichMap.Remove( 0, aWhichMap.Count() );
1209 aWhichMap.Insert( (USHORT)0, (USHORT)0 );
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, (USHORT*)aPardMap.GetData(), aPardMap.Count() );
1215 SvParser::BuildWhichTbl( aWhichMap, (USHORT*)aPlainMap.GetData(), aPlainMap.Count() );
1218 const SfxItemSet& SvxRTFParser::GetRTFDefaults()
1220 if( !pRTFDefaults )
1222 pRTFDefaults = new SfxItemSet( *pAttrPool, aWhichMap.GetData() );
1223 USHORT nId;
1224 if( 0 != ( nId = ((RTFPardAttrMapIds*)aPardMap.GetData())->nScriptSpace ))
1226 SvxScriptSpaceItem aItem( FALSE, nId );
1227 if( bNewDoc )
1228 pAttrPool->SetPoolDefaultItem( aItem );
1229 else
1230 pRTFDefaults->Put( aItem );
1233 return *pRTFDefaults;
1236 /*\f*/
1238 SvxRTFStyleType::SvxRTFStyleType( SfxItemPool& rPool, const USHORT* pWhichRange )
1239 : aAttrSet( rPool, pWhichRange )
1241 nOutlineNo = BYTE(-1); // nicht gesetzt
1242 nBasedOn = 0;
1243 bBasedOnIsSet = FALSE; //$flr #117411#
1244 nNext = 0;
1245 bIsCharFmt = FALSE;
1249 SvxRTFItemStackType::SvxRTFItemStackType(
1250 SfxItemPool& rPool, const USHORT* pWhichRange,
1251 const SvxPosition& rPos )
1252 : aAttrSet( rPool, pWhichRange ),
1253 pChildList( 0 ),
1254 nStyleNo( 0 )
1256 pSttNd = rPos.MakeNodeIdx();
1257 nSttCnt = rPos.GetCntIdx();
1258 pEndNd = pSttNd;
1259 nEndCnt = nSttCnt;
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 )
1270 pSttNd = rPos.MakeNodeIdx();
1271 nSttCnt = rPos.GetCntIdx();
1272 pEndNd = pSttNd;
1273 nEndCnt = nSttCnt;
1275 aAttrSet.SetParent( &rCpy.aAttrSet );
1276 if( bCopyAttr )
1277 aAttrSet.Put( rCpy.aAttrSet );
1280 SvxRTFItemStackType::~SvxRTFItemStackType()
1282 if( pChildList )
1283 delete pChildList;
1284 if( pSttNd != pEndNd )
1285 delete pEndNd;
1286 delete pSttNd;
1289 void SvxRTFItemStackType::Add( SvxRTFItemStackType* pIns )
1291 if( !pChildList )
1292 pChildList = new SvxRTFItemStackList( 4, 16 );
1293 pChildList->Insert( pIns, pChildList->Count() );
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 )
1301 delete pSttNd;
1302 pSttNd = rPos.MakeNodeIdx();
1303 nSttCnt = rPos.GetCntIdx();
1304 pEndNd = pSttNd;
1305 nEndCnt = nEndCnt;
1307 #else
1308 void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos )
1310 if (pSttNd != pEndNd)
1311 delete pEndNd;
1312 delete pSttNd;
1313 pSttNd = rPos.MakeNodeIdx();
1314 pEndNd = pSttNd;
1315 nSttCnt = rPos.GetCntIdx();
1317 #endif
1319 void SvxRTFItemStackType::MoveFullNode(const SvxNodeIdx &rOldNode,
1320 const SvxNodeIdx &rNewNode)
1322 bool bSameEndAsStart = (pSttNd == pEndNd) ? true : false;
1324 if (GetSttNodeIdx() == rOldNode.GetIdx())
1326 delete pSttNd;
1327 pSttNd = rNewNode.Clone();
1328 if (bSameEndAsStart)
1329 pEndNd = pSttNd;
1332 if (!bSameEndAsStart && GetEndNodeIdx() == rOldNode.GetIdx())
1334 delete pEndNd;
1335 pEndNd = rNewNode.Clone();
1338 //And the same for all the children
1339 USHORT nCount = pChildList ? pChildList->Count() : 0;
1340 for (USHORT i = 0; i < nCount; ++i)
1342 SvxRTFItemStackType* pStk = (*pChildList)[i];
1343 pStk->MoveFullNode(rOldNode, rNewNode);
1347 bool SvxRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &) const
1349 return false;
1352 void SvxRTFItemStackType::Compress( const SvxRTFParser& rParser )
1354 DBG_ASSERT( pChildList, "es gibt keine ChildListe" );
1356 USHORT n;
1357 SvxRTFItemStackType* pTmp = (*pChildList)[0];
1359 if( !pTmp->aAttrSet.Count() ||
1360 pSttNd->GetIdx() != pTmp->pSttNd->GetIdx() ||
1361 nSttCnt != pTmp->nSttCnt )
1362 return;
1364 SvxNodeIdx* pLastNd = pTmp->pEndNd;
1365 xub_StrLen nLastCnt = pTmp->nEndCnt;
1367 SfxItemSet aMrgSet( pTmp->aAttrSet );
1368 for( n = 1; n < pChildList->Count(); ++n )
1370 pTmp = (*pChildList)[n];
1371 if( pTmp->pChildList )
1372 pTmp->Compress( rParser );
1374 if( !pTmp->nSttCnt
1375 ? (pLastNd->GetIdx()+1 != pTmp->pSttNd->GetIdx() ||
1376 !rParser.IsEndPara( pLastNd, nLastCnt ) )
1377 : ( pTmp->nSttCnt != nLastCnt ||
1378 pLastNd->GetIdx() != pTmp->pSttNd->GetIdx() ))
1380 while( ++n < pChildList->Count() )
1381 if( (pTmp = (*pChildList)[n])->pChildList )
1382 pTmp->Compress( rParser );
1383 return;
1386 if (rParser.UncompressableStackEntry(*pTmp))
1387 return;
1389 if( n )
1391 // suche alle, die ueber den gesamten Bereich gesetzt sind
1392 SfxItemIter aIter( aMrgSet );
1393 const SfxPoolItem* pItem;
1394 do {
1395 USHORT nWhich = aIter.GetCurItem()->Which();
1396 if( SFX_ITEM_SET != pTmp->aAttrSet.GetItemState( nWhich,
1397 FALSE, &pItem ) || *pItem != *aIter.GetCurItem() )
1398 aMrgSet.ClearItem( nWhich );
1400 if( aIter.IsAtEnd() )
1401 break;
1402 aIter.NextItem();
1403 } while( TRUE );
1405 if( !aMrgSet.Count() )
1406 return;
1409 pLastNd = pTmp->pEndNd;
1410 nLastCnt = pTmp->nEndCnt;
1413 if( pEndNd->GetIdx() != pLastNd->GetIdx() || nEndCnt != nLastCnt )
1414 return;
1416 // es kann zusammengefasst werden
1417 aAttrSet.Put( aMrgSet );
1419 for( n = 0; n < pChildList->Count(); ++n )
1421 pTmp = (*pChildList)[n];
1422 pTmp->aAttrSet.Differentiate( aMrgSet );
1424 if( !pTmp->pChildList && !pTmp->aAttrSet.Count() && !pTmp->nStyleNo )
1426 pChildList->Remove( n );
1427 delete pTmp;
1428 --n;
1429 continue;
1432 if( !pChildList->Count() )
1434 delete pChildList;
1435 pChildList = 0;
1438 void SvxRTFItemStackType::SetRTFDefaults( const SfxItemSet& rDefaults )
1440 if( rDefaults.Count() )
1442 SfxItemIter aIter( rDefaults );
1443 do {
1444 USHORT nWhich = aIter.GetCurItem()->Which();
1445 if( SFX_ITEM_SET != aAttrSet.GetItemState( nWhich, FALSE ))
1446 aAttrSet.Put( *aIter.GetCurItem() );
1448 if( aIter.IsAtEnd() )
1449 break;
1450 aIter.NextItem();
1451 } while( TRUE );
1455 /*\f*/
1457 RTFPlainAttrMapIds::RTFPlainAttrMapIds( const SfxItemPool& rPool )
1459 nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, FALSE );
1460 nBgColor = rPool.GetTrueWhich( SID_ATTR_BRUSH_CHAR, FALSE );
1461 nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, FALSE );
1462 nContour = rPool.GetTrueWhich( SID_ATTR_CHAR_CONTOUR, FALSE );
1463 nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, FALSE );
1464 nEscapement = rPool.GetTrueWhich( SID_ATTR_CHAR_ESCAPEMENT, FALSE );
1465 nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, FALSE );
1466 nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, FALSE );
1467 nKering = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, FALSE );
1468 nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, FALSE );
1469 nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, FALSE );
1470 nShadowed = rPool.GetTrueWhich( SID_ATTR_CHAR_SHADOWED, FALSE );
1471 nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, FALSE );
1472 nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, FALSE );
1473 nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, FALSE );
1474 nWordlineMode = rPool.GetTrueWhich( SID_ATTR_CHAR_WORDLINEMODE, FALSE );
1475 nAutoKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_AUTOKERN, FALSE );
1477 nCJKFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, FALSE );
1478 nCJKFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, FALSE );
1479 nCJKLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, FALSE );
1480 nCJKPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, FALSE );
1481 nCJKWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, FALSE );
1482 nCTLFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, FALSE );
1483 nCTLFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, FALSE );
1484 nCTLLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, FALSE );
1485 nCTLPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, FALSE );
1486 nCTLWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, FALSE );
1487 nEmphasis = rPool.GetTrueWhich( SID_ATTR_CHAR_EMPHASISMARK, FALSE );
1488 nTwoLines = rPool.GetTrueWhich( SID_ATTR_CHAR_TWO_LINES, FALSE );
1489 nRuby = 0; //rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_RUBY, FALSE );
1490 nCharScaleX = rPool.GetTrueWhich( SID_ATTR_CHAR_SCALEWIDTH, FALSE );
1491 nHorzVert = rPool.GetTrueWhich( SID_ATTR_CHAR_ROTATED, FALSE );
1492 nRelief = rPool.GetTrueWhich( SID_ATTR_CHAR_RELIEF, FALSE );
1493 nHidden = rPool.GetTrueWhich( SID_ATTR_CHAR_HIDDEN, FALSE );
1496 RTFPardAttrMapIds ::RTFPardAttrMapIds ( const SfxItemPool& rPool )
1498 nLinespacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, FALSE );
1499 nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, FALSE );
1500 nTabStop = rPool.GetTrueWhich( SID_ATTR_TABSTOP, FALSE );
1501 nHyphenzone = rPool.GetTrueWhich( SID_ATTR_PARA_HYPHENZONE, FALSE );
1502 nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, FALSE );
1503 nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, FALSE );
1504 nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, FALSE );
1505 nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, FALSE );
1506 nShadow = rPool.GetTrueWhich( SID_ATTR_BORDER_SHADOW, FALSE );
1507 nOutlineLvl = rPool.GetTrueWhich( SID_ATTR_PARA_OUTLLEVEL, FALSE );
1508 nSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, FALSE );
1509 nKeep = rPool.GetTrueWhich( SID_ATTR_PARA_KEEP, FALSE );
1510 nFontAlign = rPool.GetTrueWhich( SID_PARA_VERTALIGN, FALSE );
1511 nScriptSpace = rPool.GetTrueWhich( SID_ATTR_PARA_SCRIPTSPACE, FALSE );
1512 nHangPunct = rPool.GetTrueWhich( SID_ATTR_PARA_HANGPUNCTUATION, FALSE );
1513 nForbRule = rPool.GetTrueWhich( SID_ATTR_PARA_FORBIDDEN_RULES, FALSE );
1514 nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, FALSE );
1517 /* vi:set tabstop=4 shiftwidth=4 expandtab: */