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