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