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 28 29 #include <ctype.h> 30 #include <tools/datetime.hxx> 31 #include <tools/diagnose_ex.h> 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 aFontTbl.Clear(); 827 } 828 829 void SvxRTFParser::ClearStyleTbl() 830 { 831 for( sal_uInt32 nCnt = aStyleTbl.Count(); nCnt; ) 832 delete aStyleTbl.GetObject( --nCnt ); 833 aStyleTbl.Clear(); 834 } 835 836 void SvxRTFParser::ClearAttrStack() 837 { 838 SvxRTFItemStackType* pTmp; 839 for( size_t nCnt = aAttrStack.size(); nCnt; --nCnt ) 840 { 841 pTmp = aAttrStack.back(); 842 aAttrStack.pop_back(); 843 delete pTmp; 844 } 845 } 846 847 String& SvxRTFParser::DelCharAtEnd( String& rStr, const sal_Unicode cDel ) 848 { 849 if( rStr.Len() && ' ' == rStr.GetChar( 0 )) 850 rStr.EraseLeadingChars(); 851 if( rStr.Len() && ' ' == rStr.GetChar( rStr.Len()-1 )) 852 rStr.EraseTrailingChars(); 853 if( rStr.Len() && cDel == rStr.GetChar( rStr.Len()-1 )) 854 rStr.Erase( rStr.Len()-1 ); 855 return rStr; 856 } 857 858 859 const Font& SvxRTFParser::GetFont( sal_uInt16 nId ) 860 { 861 const Font* pFont = aFontTbl.Get( nId ); 862 if( !pFont ) 863 { 864 const SvxFontItem& rDfltFont = (const SvxFontItem&) 865 pAttrPool->GetDefaultItem( 866 ((RTFPlainAttrMapIds*)aPlainMap.GetData())->nFont ); 867 pDfltFont->SetName( rDfltFont.GetStyleName() ); 868 pDfltFont->SetFamily( rDfltFont.GetFamily() ); 869 pFont = pDfltFont; 870 } 871 return *pFont; 872 } 873 874 SvxRTFItemStackType* SvxRTFParser::_GetAttrSet( int bCopyAttr ) 875 { 876 SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back(); 877 SvxRTFItemStackType* pNew; 878 if( pAkt ) 879 pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, bCopyAttr ); 880 else 881 pNew = new SvxRTFItemStackType( *pAttrPool, aWhichMap.GetData(), 882 *pInsPos ); 883 pNew->SetRTFDefaults( GetRTFDefaults() ); 884 885 aAttrStack.push_back( pNew ); 886 bNewGroup = sal_False; 887 return pNew; 888 } 889 890 891 void SvxRTFParser::_ClearStyleAttr( SvxRTFItemStackType& rStkType ) 892 { 893 // check attributes to the attributes of the stylesheet or to 894 // the default attrs of the document 895 SfxItemSet &rSet = rStkType.GetAttrSet(); 896 const SfxItemPool& rPool = *rSet.GetPool(); 897 const SfxPoolItem* pItem; 898 SfxWhichIter aIter( rSet ); 899 900 SvxRTFStyleType* pStyle; 901 if( !IsChkStyleAttr() || 902 !rStkType.GetAttrSet().Count() || 903 0 == ( pStyle = aStyleTbl.Get( rStkType.nStyleNo ) )) 904 { 905 for( sal_uInt16 nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() ) 906 { 907 if( SFX_WHICH_MAX > nWhich && 908 SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem ) && 909 rPool.GetDefaultItem( nWhich ) == *pItem ) 910 rSet.ClearItem( nWhich ); // loeschen 911 } 912 } 913 else 914 { 915 // alle Attribute, die schon vom Style definiert sind, aus dem 916 // akt. AttrSet entfernen 917 SfxItemSet &rStyleSet = pStyle->aAttrSet; 918 const SfxPoolItem* pSItem; 919 for( sal_uInt16 nWhich = aIter.GetCurWhich(); nWhich; nWhich = aIter.NextWhich() ) 920 { 921 if( SFX_ITEM_SET == rStyleSet.GetItemState( nWhich, sal_True, &pSItem )) 922 { 923 // JP 22.06.99: im Style und im Set gleich gesetzt -> loeschen 924 if( SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem ) 925 && *pItem == *pSItem ) 926 rSet.ClearItem( nWhich ); // loeschen 927 } 928 // Bug 59571 - falls nicht im Style gesetzt und gleich mit 929 // dem PoolDefault -> auch dann loeschen 930 else if( SFX_WHICH_MAX > nWhich && 931 SFX_ITEM_SET == rSet.GetItemState( nWhich, sal_False, &pItem ) && 932 rPool.GetDefaultItem( nWhich ) == *pItem ) 933 rSet.ClearItem( nWhich ); // loeschen 934 } 935 } 936 } 937 938 void SvxRTFParser::AttrGroupEnd() // den akt. Bearbeiten, vom Stack loeschen 939 { 940 if( !aAttrStack.empty() ) 941 { 942 SvxRTFItemStackType *pOld = aAttrStack.empty() ? 0 : aAttrStack.back(); 943 aAttrStack.pop_back(); 944 SvxRTFItemStackType *pAkt = aAttrStack.empty() ? 0 : aAttrStack.back(); 945 946 do { // middle check loop 947 sal_uLong nOldSttNdIdx = pOld->pSttNd->GetIdx(); 948 if( !pOld->pChildList && 949 ((!pOld->aAttrSet.Count() && !pOld->nStyleNo ) || 950 (nOldSttNdIdx == pInsPos->GetNodeIdx() && 951 pOld->nSttCnt == pInsPos->GetCntIdx() ))) 952 break; // keine Attribute oder Bereich 953 954 // setze nur die Attribute, die unterschiedlich zum Parent sind 955 if( pAkt && pOld->aAttrSet.Count() ) 956 { 957 SfxItemIter aIter( pOld->aAttrSet ); 958 const SfxPoolItem* pItem = aIter.GetCurItem(), *pGet; 959 while( sal_True ) 960 { 961 if( SFX_ITEM_SET == pAkt->aAttrSet.GetItemState( 962 pItem->Which(), sal_False, &pGet ) && 963 *pItem == *pGet ) 964 pOld->aAttrSet.ClearItem( pItem->Which() ); 965 966 if( aIter.IsAtEnd() ) 967 break; 968 pItem = aIter.NextItem(); 969 } 970 971 if( !pOld->aAttrSet.Count() && !pOld->pChildList && 972 !pOld->nStyleNo ) 973 break; 974 } 975 976 // setze alle Attribute, die von Start bis hier 977 // definiert sind. 978 int bCrsrBack = !pInsPos->GetCntIdx(); 979 if( bCrsrBack ) 980 { 981 // am Absatzanfang ? eine Position zurueck 982 sal_uLong nNd = pInsPos->GetNodeIdx(); 983 MovePos( sal_False ); 984 // if can not move backward then later don't move forward ! 985 bCrsrBack = nNd != pInsPos->GetNodeIdx(); 986 } 987 988 //Bug #46608#: ungueltige Bereiche ignorieren! 989 if( ( pOld->pSttNd->GetIdx() < pInsPos->GetNodeIdx() || 990 ( pOld->pSttNd->GetIdx() == pInsPos->GetNodeIdx() && 991 pOld->nSttCnt <= pInsPos->GetCntIdx() )) 992 #if 0 993 //BUG 68555 - don't test for empty paragraph or any range 994 && ( nOldSttNdIdx != pInsPos->GetNodeIdx() || 995 pOld->nSttCnt != pInsPos->GetCntIdx() || 996 !pOld->nSttCnt ) 997 #endif 998 ) 999 { 1000 if( !bCrsrBack ) 1001 { 1002 // alle pard-Attribute gelten nur bis zum vorherigen 1003 // Absatz !! 1004 if( nOldSttNdIdx == pInsPos->GetNodeIdx() ) 1005 { 1006 #if 0 1007 //BUG 68555 - don't reset pard attrs, if the group not begins not at start of 1008 // paragraph 1009 // Bereich innerhalb eines Absatzes: 1010 // alle Absatz-Attribute und StyleNo loeschen 1011 // aber nur wenn mitten drin angefangen wurde 1012 if( pOld->nSttCnt ) 1013 { 1014 pOld->nStyleNo = 0; 1015 for( sal_uInt16 n = 0; n < aPardMap.Count() && 1016 pOld->aAttrSet.Count(); ++n ) 1017 if( aPardMap[n] ) 1018 pOld->aAttrSet.ClearItem( aPardMap[n] ); 1019 1020 if( !pOld->aAttrSet.Count() && !pOld->pChildList && 1021 !pOld->nStyleNo ) 1022 break; // auch dieser verlaesst uns jetzt 1023 } 1024 #endif 1025 } 1026 else 1027 { 1028 // jetzt wirds kompliziert: 1029 // - alle Zeichen-Attribute behalten den Bereich, 1030 // - alle Absatz-Attribute bekommen den Bereich 1031 // bis zum vorherigen Absatz 1032 SvxRTFItemStackType* pNew = new SvxRTFItemStackType( 1033 *pOld, *pInsPos, sal_True ); 1034 pNew->aAttrSet.SetParent( pOld->aAttrSet.GetParent() ); 1035 1036 // loesche aus pNew alle Absatz Attribute 1037 for( sal_uInt16 n = 0; n < aPardMap.Count() && 1038 pNew->aAttrSet.Count(); ++n ) 1039 if( aPardMap[n] ) 1040 pNew->aAttrSet.ClearItem( aPardMap[n] ); 1041 pNew->SetRTFDefaults( GetRTFDefaults() ); 1042 1043 // gab es ueberhaupt welche ? 1044 if( pNew->aAttrSet.Count() == pOld->aAttrSet.Count() ) 1045 delete pNew; // das wars dann 1046 else 1047 { 1048 pNew->nStyleNo = 0; 1049 1050 // spanne jetzt den richtigen Bereich auf 1051 // pNew von alter 1052 SetEndPrevPara( pOld->pEndNd, pOld->nEndCnt ); 1053 pNew->nSttCnt = 0; 1054 1055 if( IsChkStyleAttr() ) 1056 { 1057 _ClearStyleAttr( *pOld ); 1058 _ClearStyleAttr( *pNew ); //#i10381#, methinks. 1059 } 1060 1061 if( pAkt ) 1062 { 1063 pAkt->Add( pOld ); 1064 pAkt->Add( pNew ); 1065 } 1066 else 1067 { 1068 // letzter vom Stack, also zwischenspeichern, bis der 1069 // naechste Text eingelesen wurde. (keine Attribute 1070 // aufspannen!!) 1071 aAttrSetList.Insert( pOld, aAttrSetList.Count() ); 1072 aAttrSetList.Insert( pNew, aAttrSetList.Count() ); 1073 } 1074 pOld = 0; // pOld nicht loeschen 1075 break; // das wars !! 1076 } 1077 } 1078 } 1079 1080 pOld->pEndNd = pInsPos->MakeNodeIdx(); 1081 pOld->nEndCnt = pInsPos->GetCntIdx(); 1082 1083 #if 0 1084 if( IsChkStyleAttr() ) 1085 _ClearStyleAttr( *pOld ); 1086 #else 1087 /* 1088 #i21422# 1089 If the parent (pAkt) sets something e.g. , and the child (pOld) 1090 unsets it and the style both are based on has it unset then 1091 clearing the pOld by looking at the style is clearly a disaster 1092 as the text ends up with pAkts bold and not pOlds no bold, this 1093 should be rethought out. For the moment its safest to just do 1094 the clean if we have no parent, all we suffer is too many 1095 redundant properties. 1096 */ 1097 if (IsChkStyleAttr() && !pAkt) 1098 _ClearStyleAttr( *pOld ); 1099 #endif 1100 1101 if( pAkt ) 1102 { 1103 pAkt->Add( pOld ); 1104 // split up and create new entry, because it make no sense 1105 // to create a "so long" depend list. Bug 95010 1106 if( bCrsrBack && 50 < pAkt->pChildList->Count() ) 1107 { 1108 // am Absatzanfang ? eine Position zurueck 1109 MovePos( sal_True ); 1110 bCrsrBack = sal_False; 1111 1112 // eine neue Gruppe aufmachen 1113 SvxRTFItemStackType* pNew = new SvxRTFItemStackType( 1114 *pAkt, *pInsPos, sal_True ); 1115 pNew->SetRTFDefaults( GetRTFDefaults() ); 1116 1117 // alle bis hierher gueltigen Attribute "setzen" 1118 AttrGroupEnd(); 1119 pAkt = aAttrStack.empty() ? 0 : aAttrStack.back(); // can be changed after AttrGroupEnd! 1120 pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 ); 1121 aAttrStack.push_back( pNew ); 1122 pAkt = pNew; 1123 } 1124 } 1125 else 1126 // letzter vom Stack, also zwischenspeichern, bis der 1127 // naechste Text eingelesen wurde. (keine Attribute 1128 // aufspannen!!) 1129 aAttrSetList.Insert( pOld, aAttrSetList.Count() ); 1130 1131 pOld = 0; 1132 } 1133 1134 if( bCrsrBack ) 1135 // am Absatzanfang ? eine Position zurueck 1136 MovePos( sal_True ); 1137 1138 } while( sal_False ); 1139 1140 if( pOld ) 1141 delete pOld; 1142 1143 bNewGroup = sal_False; 1144 } 1145 } 1146 1147 void SvxRTFParser::SetAllAttrOfStk() // end all Attr. and set it into doc 1148 { 1149 // repeat until all attributes will be taken from stack 1150 while( !aAttrStack.empty() ) 1151 AttrGroupEnd(); 1152 1153 for( sal_uInt16 n = aAttrSetList.Count(); n; ) 1154 { 1155 SvxRTFItemStackType* pStkSet = aAttrSetList[--n]; 1156 SetAttrSet( *pStkSet ); 1157 aAttrSetList.DeleteAndDestroy( n ); 1158 } 1159 } 1160 1161 // setzt alle Attribute, die unterschiedlich zum aktuellen sind 1162 void SvxRTFParser::SetAttrSet( SvxRTFItemStackType &rSet ) 1163 { 1164 // wurde DefTab nie eingelesen? dann setze auf default 1165 if( !bIsSetDfltTab ) 1166 SetDefault( RTF_DEFTAB, 720 ); 1167 1168 if( rSet.pChildList ) 1169 rSet.Compress( *this ); 1170 if( rSet.aAttrSet.Count() || rSet.nStyleNo ) 1171 SetAttrInDoc( rSet ); 1172 1173 // dann mal alle Childs abarbeiten 1174 if( rSet.pChildList ) 1175 for( sal_uInt16 n = 0; n < rSet.pChildList->Count(); ++n ) 1176 SetAttrSet( *(*rSet.pChildList)[ n ] ); 1177 } 1178 1179 // Is text wasn't inserted? (Get SttPos from the top of stack!) 1180 int SvxRTFParser::IsAttrSttPos() 1181 { 1182 SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back(); 1183 return !pAkt || (pAkt->pSttNd->GetIdx() == pInsPos->GetNodeIdx() && 1184 pAkt->nSttCnt == pInsPos->GetCntIdx()); 1185 } 1186 1187 1188 void SvxRTFParser::SetAttrInDoc( SvxRTFItemStackType & ) 1189 { 1190 } 1191 1192 #ifdef USED 1193 void SvxRTFParser::SaveState( int nToken ) 1194 { 1195 SvRTFParser::SaveState( nToken ); 1196 } 1197 1198 void SvxRTFParser::RestoreState() 1199 { 1200 SvRTFParser::RestoreState(); 1201 } 1202 #endif 1203 1204 void SvxRTFParser::BuildWhichTbl() 1205 { 1206 if( aWhichMap.Count() ) 1207 aWhichMap.Remove( 0, aWhichMap.Count() ); 1208 aWhichMap.Insert( (sal_uInt16)0, (sal_uInt16)0 ); 1209 1210 // Aufbau einer Which-Map 'rWhichMap' aus einem Array von 1211 // 'pWhichIds' von Which-Ids. Es hat die Lange 'nWhichIds'. 1212 // Die Which-Map wird nicht geloescht. 1213 SvParser::BuildWhichTbl( aWhichMap, (sal_uInt16*)aPardMap.GetData(), aPardMap.Count() ); 1214 SvParser::BuildWhichTbl( aWhichMap, (sal_uInt16*)aPlainMap.GetData(), aPlainMap.Count() ); 1215 } 1216 1217 const SfxItemSet& SvxRTFParser::GetRTFDefaults() 1218 { 1219 if( !pRTFDefaults ) 1220 { 1221 pRTFDefaults = new SfxItemSet( *pAttrPool, aWhichMap.GetData() ); 1222 sal_uInt16 nId; 1223 if( 0 != ( nId = ((RTFPardAttrMapIds*)aPardMap.GetData())->nScriptSpace )) 1224 { 1225 SvxScriptSpaceItem aItem( sal_False, nId ); 1226 if( bNewDoc ) 1227 pAttrPool->SetPoolDefaultItem( aItem ); 1228 else 1229 pRTFDefaults->Put( aItem ); 1230 } 1231 } 1232 return *pRTFDefaults; 1233 } 1234 1235 /**/ 1236 1237 SvxRTFStyleType::SvxRTFStyleType( SfxItemPool& rPool, const sal_uInt16* pWhichRange ) 1238 : aAttrSet( rPool, pWhichRange ) 1239 { 1240 nOutlineNo = sal_uInt8(-1); // nicht gesetzt 1241 nBasedOn = 0; 1242 bBasedOnIsSet = sal_False; //$flr #117411# 1243 nNext = 0; 1244 bIsCharFmt = sal_False; 1245 } 1246 1247 1248 SvxRTFItemStackType::SvxRTFItemStackType( 1249 SfxItemPool& rPool, const sal_uInt16* pWhichRange, 1250 const SvxPosition& rPos ) 1251 : aAttrSet( rPool, pWhichRange ), 1252 pChildList( 0 ), 1253 nStyleNo( 0 ) 1254 { 1255 pSttNd = rPos.MakeNodeIdx(); 1256 nSttCnt = rPos.GetCntIdx(); 1257 pEndNd = pSttNd; 1258 nEndCnt = nSttCnt; 1259 } 1260 1261 SvxRTFItemStackType::SvxRTFItemStackType( 1262 const SvxRTFItemStackType& rCpy, 1263 const SvxPosition& rPos, 1264 int bCopyAttr ) 1265 : aAttrSet( *rCpy.aAttrSet.GetPool(), rCpy.aAttrSet.GetRanges() ), 1266 pChildList( 0 ), 1267 nStyleNo( rCpy.nStyleNo ) 1268 { 1269 pSttNd = rPos.MakeNodeIdx(); 1270 nSttCnt = rPos.GetCntIdx(); 1271 pEndNd = pSttNd; 1272 nEndCnt = nSttCnt; 1273 1274 aAttrSet.SetParent( &rCpy.aAttrSet ); 1275 if( bCopyAttr ) 1276 aAttrSet.Put( rCpy.aAttrSet ); 1277 } 1278 1279 SvxRTFItemStackType::~SvxRTFItemStackType() 1280 { 1281 if( pChildList ) 1282 delete pChildList; 1283 if( pSttNd != pEndNd ) 1284 delete pEndNd; 1285 delete pSttNd; 1286 } 1287 1288 void SvxRTFItemStackType::Add( SvxRTFItemStackType* pIns ) 1289 { 1290 if( !pChildList ) 1291 pChildList = new SvxRTFItemStackList( 4, 16 ); 1292 pChildList->Insert( pIns, pChildList->Count() ); 1293 } 1294 1295 #if 0 1296 //cmc: This is the original. nEndCnt is redundantly assigned to itself, and 1297 //pEndNd can leak if not equal to pSttNd. 1298 void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos ) 1299 { 1300 delete pSttNd; 1301 pSttNd = rPos.MakeNodeIdx(); 1302 nSttCnt = rPos.GetCntIdx(); 1303 pEndNd = pSttNd; 1304 nEndCnt = nEndCnt; 1305 } 1306 #else 1307 void SvxRTFItemStackType::SetStartPos( const SvxPosition& rPos ) 1308 { 1309 if (pSttNd != pEndNd) 1310 delete pEndNd; 1311 delete pSttNd; 1312 pSttNd = rPos.MakeNodeIdx(); 1313 pEndNd = pSttNd; 1314 nSttCnt = rPos.GetCntIdx(); 1315 } 1316 #endif 1317 1318 void SvxRTFItemStackType::MoveFullNode(const SvxNodeIdx &rOldNode, 1319 const SvxNodeIdx &rNewNode) 1320 { 1321 bool bSameEndAsStart = (pSttNd == pEndNd) ? true : false; 1322 1323 if (GetSttNodeIdx() == rOldNode.GetIdx()) 1324 { 1325 delete pSttNd; 1326 pSttNd = rNewNode.Clone(); 1327 if (bSameEndAsStart) 1328 pEndNd = pSttNd; 1329 } 1330 1331 if (!bSameEndAsStart && GetEndNodeIdx() == rOldNode.GetIdx()) 1332 { 1333 delete pEndNd; 1334 pEndNd = rNewNode.Clone(); 1335 } 1336 1337 //And the same for all the children 1338 sal_uInt16 nCount = pChildList ? pChildList->Count() : 0; 1339 for (sal_uInt16 i = 0; i < nCount; ++i) 1340 { 1341 SvxRTFItemStackType* pStk = (*pChildList)[i]; 1342 pStk->MoveFullNode(rOldNode, rNewNode); 1343 } 1344 } 1345 1346 bool SvxRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &) const 1347 { 1348 return false; 1349 } 1350 1351 void SvxRTFItemStackType::Compress( const SvxRTFParser& rParser ) 1352 { 1353 ENSURE_OR_RETURN_VOID(pChildList, "Compress: no ChildList" ); 1354 ENSURE_OR_RETURN_VOID(pChildList->Count(), "Compress: ChildList empty"); 1355 1356 sal_uInt16 n; 1357 SvxRTFItemStackType* pTmp = (*pChildList)[0]; 1358 1359 if( !pTmp->aAttrSet.Count() || 1360 pSttNd->GetIdx() != pTmp->pSttNd->GetIdx() || 1361 nSttCnt != pTmp->nSttCnt ) 1362 return; 1363 1364 SvxNodeIdx* pLastNd = pTmp->pEndNd; 1365 xub_StrLen nLastCnt = pTmp->nEndCnt; 1366 1367 SfxItemSet aMrgSet( pTmp->aAttrSet ); 1368 for( n = 1; n < pChildList->Count(); ++n ) 1369 { 1370 pTmp = (*pChildList)[n]; 1371 if( pTmp->pChildList ) 1372 pTmp->Compress( rParser ); 1373 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() )) 1379 { 1380 while( ++n < pChildList->Count() ) 1381 if( (pTmp = (*pChildList)[n])->pChildList ) 1382 pTmp->Compress( rParser ); 1383 return; 1384 } 1385 1386 if (rParser.UncompressableStackEntry(*pTmp)) 1387 return; 1388 1389 if( n ) 1390 { 1391 // suche alle, die ueber den gesamten Bereich gesetzt sind 1392 SfxItemIter aIter( aMrgSet ); 1393 const SfxPoolItem* pItem; 1394 do { 1395 sal_uInt16 nWhich = aIter.GetCurItem()->Which(); 1396 if( SFX_ITEM_SET != pTmp->aAttrSet.GetItemState( nWhich, 1397 sal_False, &pItem ) || *pItem != *aIter.GetCurItem() ) 1398 aMrgSet.ClearItem( nWhich ); 1399 1400 if( aIter.IsAtEnd() ) 1401 break; 1402 aIter.NextItem(); 1403 } while( sal_True ); 1404 1405 if( !aMrgSet.Count() ) 1406 return; 1407 } 1408 1409 pLastNd = pTmp->pEndNd; 1410 nLastCnt = pTmp->nEndCnt; 1411 } 1412 1413 if( pEndNd->GetIdx() != pLastNd->GetIdx() || nEndCnt != nLastCnt ) 1414 return; 1415 1416 // es kann zusammengefasst werden 1417 aAttrSet.Put( aMrgSet ); 1418 1419 for( n = 0; n < pChildList->Count(); ++n ) 1420 { 1421 pTmp = (*pChildList)[n]; 1422 pTmp->aAttrSet.Differentiate( aMrgSet ); 1423 1424 if( !pTmp->pChildList && !pTmp->aAttrSet.Count() && !pTmp->nStyleNo ) 1425 { 1426 pChildList->Remove( n ); 1427 delete pTmp; 1428 --n; 1429 continue; 1430 } 1431 } 1432 if( !pChildList->Count() ) 1433 { 1434 delete pChildList; 1435 pChildList = 0; 1436 } 1437 } 1438 void SvxRTFItemStackType::SetRTFDefaults( const SfxItemSet& rDefaults ) 1439 { 1440 if( rDefaults.Count() ) 1441 { 1442 SfxItemIter aIter( rDefaults ); 1443 do { 1444 sal_uInt16 nWhich = aIter.GetCurItem()->Which(); 1445 if( SFX_ITEM_SET != aAttrSet.GetItemState( nWhich, sal_False )) 1446 aAttrSet.Put( *aIter.GetCurItem() ); 1447 1448 if( aIter.IsAtEnd() ) 1449 break; 1450 aIter.NextItem(); 1451 } while( sal_True ); 1452 } 1453 } 1454 1455 /**/ 1456 1457 RTFPlainAttrMapIds::RTFPlainAttrMapIds( const SfxItemPool& rPool ) 1458 { 1459 nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, sal_False ); 1460 nBgColor = rPool.GetTrueWhich( SID_ATTR_BRUSH_CHAR, sal_False ); 1461 nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, sal_False ); 1462 nContour = rPool.GetTrueWhich( SID_ATTR_CHAR_CONTOUR, sal_False ); 1463 nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, sal_False ); 1464 nEscapement = rPool.GetTrueWhich( SID_ATTR_CHAR_ESCAPEMENT, sal_False ); 1465 nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, sal_False ); 1466 nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, sal_False ); 1467 nKering = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, sal_False ); 1468 nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, sal_False ); 1469 nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, sal_False ); 1470 nShadowed = rPool.GetTrueWhich( SID_ATTR_CHAR_SHADOWED, sal_False ); 1471 nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, sal_False ); 1472 nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, sal_False ); 1473 nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, sal_False ); 1474 nWordlineMode = rPool.GetTrueWhich( SID_ATTR_CHAR_WORDLINEMODE, sal_False ); 1475 nAutoKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_AUTOKERN, sal_False ); 1476 1477 nCJKFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, sal_False ); 1478 nCJKFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, sal_False ); 1479 nCJKLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, sal_False ); 1480 nCJKPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, sal_False ); 1481 nCJKWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, sal_False ); 1482 nCTLFont = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, sal_False ); 1483 nCTLFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, sal_False ); 1484 nCTLLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, sal_False ); 1485 nCTLPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, sal_False ); 1486 nCTLWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, sal_False ); 1487 nEmphasis = rPool.GetTrueWhich( SID_ATTR_CHAR_EMPHASISMARK, sal_False ); 1488 nTwoLines = rPool.GetTrueWhich( SID_ATTR_CHAR_TWO_LINES, sal_False ); 1489 nRuby = 0; //rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_RUBY, sal_False ); 1490 nCharScaleX = rPool.GetTrueWhich( SID_ATTR_CHAR_SCALEWIDTH, sal_False ); 1491 nHorzVert = rPool.GetTrueWhich( SID_ATTR_CHAR_ROTATED, sal_False ); 1492 nRelief = rPool.GetTrueWhich( SID_ATTR_CHAR_RELIEF, sal_False ); 1493 nHidden = rPool.GetTrueWhich( SID_ATTR_CHAR_HIDDEN, sal_False ); 1494 } 1495 1496 RTFPardAttrMapIds ::RTFPardAttrMapIds ( const SfxItemPool& rPool ) 1497 { 1498 nLinespacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, sal_False ); 1499 nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, sal_False ); 1500 nTabStop = rPool.GetTrueWhich( SID_ATTR_TABSTOP, sal_False ); 1501 nHyphenzone = rPool.GetTrueWhich( SID_ATTR_PARA_HYPHENZONE, sal_False ); 1502 nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, sal_False ); 1503 nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, sal_False ); 1504 nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, sal_False ); 1505 nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, sal_False ); 1506 nShadow = rPool.GetTrueWhich( SID_ATTR_BORDER_SHADOW, sal_False ); 1507 nOutlineLvl = rPool.GetTrueWhich( SID_ATTR_PARA_OUTLLEVEL, sal_False ); 1508 nSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, sal_False ); 1509 nKeep = rPool.GetTrueWhich( SID_ATTR_PARA_KEEP, sal_False ); 1510 nFontAlign = rPool.GetTrueWhich( SID_PARA_VERTALIGN, sal_False ); 1511 nScriptSpace = rPool.GetTrueWhich( SID_ATTR_PARA_SCRIPTSPACE, sal_False ); 1512 nHangPunct = rPool.GetTrueWhich( SID_ATTR_PARA_HANGPUNCTUATION, sal_False ); 1513 nForbRule = rPool.GetTrueWhich( SID_ATTR_PARA_FORBIDDEN_RULES, sal_False ); 1514 nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, sal_False ); 1515 } 1516 1517 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 1518