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