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_sw.hxx" 26 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ 27 #include <hintids.hxx> 28 29 #include <stack> 30 31 #include <tools/errinf.hxx> 32 #include <tools/stream.hxx> 33 #include <svl/itemiter.hxx> 34 #include <svtools/rtftoken.h> 35 #include <svl/intitem.hxx> 36 #include <editeng/fhgtitem.hxx> 37 #include <editeng/ulspitem.hxx> 38 #include <editeng/tstpitem.hxx> 39 #include <editeng/lspcitem.hxx> 40 #include <editeng/lrspitem.hxx> 41 #include <editeng/escpitem.hxx> 42 #include <editeng/fontitem.hxx> 43 #include <editeng/frmdiritem.hxx> 44 #include <editeng/hyznitem.hxx> 45 #include <fmtpdsc.hxx> 46 #include <fmtfld.hxx> 47 #include <fmthdft.hxx> 48 #include <fmtcntnt.hxx> 49 #include <txtftn.hxx> 50 #include <fmtclds.hxx> 51 #include <fmtftn.hxx> 52 #include <fmtfsize.hxx> 53 #include <fmtflcnt.hxx> 54 #include <fmtanchr.hxx> 55 #include <frmatr.hxx> 56 #include <docstat.hxx> 57 #include <swtable.hxx> 58 #include <shellio.hxx> 59 #include <swtypes.hxx> 60 #include <ndtxt.hxx> 61 #include <doc.hxx> 62 #include <docary.hxx> 63 #include <pam.hxx> 64 #include <mdiexp.hxx> // ...Percent() 65 #include <swparrtf.hxx> 66 #include <charfmt.hxx> 67 #include <pagedesc.hxx> 68 #include <ftninfo.hxx> 69 #include <docufld.hxx> 70 #include <flddat.hxx> 71 #include <fltini.hxx> 72 #include <fchrfmt.hxx> 73 #include <paratr.hxx> 74 #include <section.hxx> 75 #include <fmtclbl.hxx> 76 #include <viewsh.hxx> 77 #include <shellres.hxx> 78 #include <hfspacingitem.hxx> 79 #include <tox.hxx> 80 #include <swerror.h> 81 #include <cmdid.h> 82 #include <statstr.hrc> // ResId fuer Statusleiste 83 #include <SwStyleNameMapper.hxx> 84 #include <tblsel.hxx> // SwSelBoxes 85 86 #include <docsh.hxx> 87 #include <fmtlsplt.hxx> // SwLayoutSplit 88 #include <editeng/keepitem.hxx> 89 #include <svx/svdopath.hxx> 90 #include <svx/svdorect.hxx> 91 92 93 #include <fmtsrnd.hxx> 94 #include <fmtfollowtextflow.hxx> 95 #include <svx/svdmodel.hxx> 96 #include <svx/svdpage.hxx> 97 #include <editeng/opaqitem.hxx> 98 #include "svx/svdograf.hxx" 99 #include <svx/xflclit.hxx> 100 #include <svx/xlnwtit.hxx> 101 #include <svx/svdoutl.hxx> 102 #include <editeng/outlobj.hxx> 103 #include <editeng/paperinf.hxx> 104 105 #include <tools/stream.hxx> 106 #include <basegfx/polygon/b2dpolygon.hxx> 107 #include <basegfx/polygon/b2dpolypolygon.hxx> 108 #include <basegfx/range/b2drange.hxx> 109 #include <vcl/salbtype.hxx> // FRound 110 111 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> 112 113 114 using namespace ::com::sun::star; 115 116 117 // einige Hilfs-Funktionen 118 // char 119 inline const SvxFontHeightItem& GetSize(const SfxItemSet& rSet,sal_Bool bInP=sal_True) 120 { return (const SvxFontHeightItem&)rSet.Get( RES_CHRATR_FONTSIZE,bInP); } 121 inline const SvxLRSpaceItem& GetLRSpace(const SfxItemSet& rSet,sal_Bool bInP=sal_True) 122 { return (const SvxLRSpaceItem&)rSet.Get( RES_LR_SPACE,bInP); } 123 124 /* */ 125 126 extern "C" SAL_DLLPUBLIC_EXPORT Reader* SAL_CALL ImportRTF() 127 { 128 return new RtfReader(); 129 } 130 131 // Aufruf fuer die allg. Reader-Schnittstelle 132 sal_uLong RtfReader::Read( SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const String &) 133 { 134 if( !pStrm ) 135 { 136 ASSERT( sal_False, "RTF-Read ohne Stream" ); 137 return ERR_SWG_READ_ERROR; 138 } 139 140 //JP 18.01.96: Alle Ueberschriften sind normalerweise ohne 141 // Kapitelnummer. Darum hier explizit abschalten 142 // weil das Default jetzt wieder auf AN ist. 143 if( !bInsertMode ) 144 { 145 Reader::SetNoOutlineNum( rDoc ); 146 147 // MIB 27.09.96: Umrandung uns Abstaende aus Frm-Vorlagen entf. 148 Reader::ResetFrmFmts( rDoc ); 149 } 150 151 sal_uLong nRet = 0; 152 SwDocShell *pDocShell(rDoc.GetDocShell()); 153 DBG_ASSERT(pDocShell, "no SwDocShell"); 154 uno::Reference<document::XDocumentProperties> xDocProps; 155 if (pDocShell) { 156 uno::Reference<document::XDocumentPropertiesSupplier> xDPS( 157 pDocShell->GetModel(), uno::UNO_QUERY_THROW); 158 xDocProps.set(xDPS->getDocumentProperties()); 159 } 160 161 SvParserRef xParser = new SwRTFParser( &rDoc, xDocProps, 162 rPam, *pStrm, rBaseURL, !bInsertMode ); 163 SvParserState eState = xParser->CallParser(); 164 if( SVPAR_PENDING != eState && SVPAR_ACCEPTED != eState ) 165 { 166 String sErr( String::CreateFromInt32( xParser->GetLineNr() )); 167 sErr += ','; 168 sErr += String::CreateFromInt32( xParser->GetLinePos() ); 169 170 nRet = *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr, 171 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR ); 172 } 173 174 175 return nRet; 176 } 177 178 sal_uLong RtfReader::Read(SvStream* pStream, SwDoc& rDoc, const String& rBaseURL, SwPaM& rPam) 179 { 180 pStrm = pStream; 181 return Read(rDoc, rBaseURL, rPam, rBaseURL); 182 } 183 184 SwRTFParser::SwRTFParser(SwDoc* pD, 185 uno::Reference<document::XDocumentProperties> i_xDocProps, 186 const SwPaM& rCrsr, SvStream& rIn, const String& rBaseURL, 187 int bReadNewDoc) : 188 SvxRTFParser(pD->GetAttrPool(), rIn, i_xDocProps, bReadNewDoc), 189 maParaStyleMapper(*pD), 190 maCharStyleMapper(*pD), 191 maSegments(*this), 192 maInsertedTables(*pD), 193 mpBookmarkStart(0), 194 mpRedlineStack(0), 195 pAuthorInfos(0), 196 pGrfAttrSet(0), 197 pTableNode(0), 198 pOldTblNd(0), 199 pSttNdIdx(0), 200 pRegionEndIdx(0), 201 pDoc(pD), 202 pRelNumRule(new SwRelNumRuleSpaces(*pD, static_cast< sal_Bool >(bReadNewDoc))), 203 pRedlineInsert(0), 204 pRedlineDelete(0), 205 sBaseURL( rBaseURL ), 206 nAktPageDesc(0), 207 nAktFirstPageDesc(0), 208 m_nCurrentBox(0), 209 nInsTblRow(USHRT_MAX), 210 nNewNumSectDef(USHRT_MAX), 211 nRowsToRepeat(0), 212 // --> OD 2008-12-22 #i83368# 213 mbReadCellWhileReadSwFly( false ), 214 // <-- 215 bTrowdRead(0), 216 nReadFlyDepth(0), 217 nZOrder(0) 218 { 219 mbIsFootnote = mbReadNoTbl = bReadSwFly = bSwPageDesc = bStyleTabValid = 220 bInPgDscTbl = bNewNumList = false; 221 bFirstContinue = true; 222 bContainsPara = false; 223 bContainsTablePara = false; 224 bNestedField = false; 225 bForceNewTable = false; 226 227 pPam = new SwPaM( *rCrsr.GetPoint() ); 228 SetInsPos( SwxPosition( pPam ) ); 229 SetChkStyleAttr( 0 != bReadNewDoc ); 230 SetCalcValue( sal_False ); 231 SetReadDocInfo( sal_True ); 232 233 // diese sollen zusaetzlich ueber \pard zurueck gesetzt werden 234 sal_uInt16 temp; 235 temp = RES_TXTATR_CHARFMT; AddPlainAttr( temp ); 236 temp = RES_PAGEDESC; AddPardAttr( temp ); 237 temp = RES_BREAK; AddPardAttr( temp ); 238 temp = RES_PARATR_NUMRULE; AddPardAttr( temp ); 239 temp = FN_PARAM_NUM_LEVEL; AddPardAttr( temp ); 240 } 241 242 // Aufruf des Parsers 243 SvParserState SwRTFParser::CallParser() 244 { 245 mbReadNoTbl = false; 246 bFirstContinue = true; 247 248 rInput.Seek(STREAM_SEEK_TO_BEGIN); 249 rInput.ResetError(); 250 251 mpRedlineStack = new sw::util::RedlineStack(*pDoc); 252 253 return SvxRTFParser::CallParser(); 254 } 255 256 bool lcl_UsedPara(SwPaM &rPam) 257 { 258 const SwCntntNode* pCNd; 259 const SfxItemSet* pSet; 260 if( rPam.GetPoint()->nContent.GetIndex() || 261 ( 0 != ( pCNd = rPam.GetCntntNode()) && 262 0 != ( pSet = pCNd->GetpSwAttrSet()) && 263 ( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False ) || 264 SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, sal_False )))) 265 return true; 266 return false; 267 } 268 269 void SwRTFParser::Continue( int nToken ) 270 { 271 if( bFirstContinue ) 272 { 273 bFirstContinue = sal_False; 274 275 if (IsNewDoc()) 276 { 277 // 278 // COMPATIBILITY FLAGS START 279 // 280 pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX, true); 281 pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES, true); 282 pDoc->set(IDocumentSettingAccess::TAB_COMPAT, true); 283 pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, true); 284 pDoc->set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, true); 285 pDoc->set(IDocumentSettingAccess::ADD_FLY_OFFSETS, true); 286 pDoc->set(IDocumentSettingAccess::ADD_EXT_LEADING, true); 287 pDoc->set(IDocumentSettingAccess::OLD_NUMBERING, false); 288 pDoc->set(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, false ); 289 pDoc->set(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, false); 290 pDoc->set(IDocumentSettingAccess::OLD_LINE_SPACING, false); 291 pDoc->set(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS, true); 292 pDoc->set(IDocumentSettingAccess::USE_FORMER_OBJECT_POS, false); 293 pDoc->set(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING, false); 294 pDoc->set(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION, true); 295 pDoc->set(IDocumentSettingAccess::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, false); // --> FME 2005-08-11 #i53199# 296 // --> FME 2006-02-10 #131283# 297 pDoc->set(IDocumentSettingAccess::TABLE_ROW_KEEP, true); 298 pDoc->set(IDocumentSettingAccess::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, true); 299 300 // 301 // COMPATIBILITY FLAGS END 302 // 303 } 304 305 // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt! 306 pSttNdIdx = new SwNodeIndex( pDoc->GetNodes() ); 307 if( !IsNewDoc() ) // in ein Dokument einfuegen ? 308 { 309 const SwPosition* pPos = pPam->GetPoint(); 310 SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode(); 311 312 pDoc->SplitNode( *pPos, false ); 313 314 *pSttNdIdx = pPos->nNode.GetIndex()-1; 315 pDoc->SplitNode( *pPos, false ); 316 317 SwPaM aInsertionRangePam( *pPos ); 318 319 pPam->Move( fnMoveBackward ); 320 321 // #106634# split any redline over the insertion point 322 aInsertionRangePam.SetMark(); 323 *aInsertionRangePam.GetPoint() = *pPam->GetPoint(); 324 aInsertionRangePam.Move( fnMoveBackward ); 325 pDoc->SplitRedline( aInsertionRangePam ); 326 327 pDoc->SetTxtFmtColl( *pPam, pDoc->GetTxtCollFromPool 328 ( RES_POOLCOLL_STANDARD, false )); 329 330 // verhinder das einlesen von Tabellen in Fussnoten / Tabellen 331 sal_uLong nNd = pPos->nNode.GetIndex(); 332 mbReadNoTbl = 0 != pSttNd->FindTableNode() || 333 ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() && 334 pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd ); 335 } 336 337 // Laufbalken anzeigen, aber nur bei synchronem Call 338 sal_uLong nCurrPos = rInput.Tell(); 339 rInput.Seek(STREAM_SEEK_TO_END); 340 rInput.ResetError(); 341 ::StartProgress( STR_STATSTR_W4WREAD, 0, rInput.Tell(), pDoc->GetDocShell()); 342 rInput.Seek( nCurrPos ); 343 rInput.ResetError(); 344 } 345 346 SvxRTFParser::Continue( nToken ); 347 348 if( SVPAR_PENDING == GetStatus() ) 349 return ; // weiter gehts beim naechsten mal 350 351 pRelNumRule->SetNumRelSpaces( *pDoc ); 352 353 // den Start wieder korrigieren 354 if( !IsNewDoc() && pSttNdIdx->GetIndex() ) 355 { 356 //die Flys muessen zuerst zurecht gerueckt werden, denn sonst wird 357 // ein am 1. Absatz verankerter Fly falsch eingefuegt 358 if( SVPAR_ACCEPTED == eState ) 359 { 360 if( aFlyArr.Count() ) 361 SetFlysInDoc(); 362 pRelNumRule->SetOultineRelSpaces( *pSttNdIdx, pPam->GetPoint()->nNode ); 363 } 364 365 SwTxtNode* pTxtNode = pSttNdIdx->GetNode().GetTxtNode(); 366 SwNodeIndex aNxtIdx( *pSttNdIdx ); 367 if( pTxtNode && pTxtNode->CanJoinNext( &aNxtIdx )) 368 { 369 xub_StrLen nStt = pTxtNode->GetTxt().Len(); 370 // wenn der Cursor noch in dem Node steht, dann setze in an das Ende 371 if( pPam->GetPoint()->nNode == aNxtIdx ) 372 { 373 pPam->GetPoint()->nNode = *pSttNdIdx; 374 pPam->GetPoint()->nContent.Assign( pTxtNode, nStt ); 375 } 376 377 #ifdef DBG_UTIL 378 // !!! sollte nicht moeglich sein, oder ?? 379 ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_True ).nNode.GetIndex(), 380 "Pam.Bound1 steht noch im Node" ); 381 ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_False ).nNode.GetIndex(), 382 "Pam.Bound2 steht noch im Node" ); 383 384 if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( sal_True ).nNode.GetIndex() ) 385 { 386 xub_StrLen nCntPos = pPam->GetBound( sal_True ).nContent.GetIndex(); 387 pPam->GetBound( sal_True ).nContent.Assign( pTxtNode, 388 pTxtNode->GetTxt().Len() + nCntPos ); 389 } 390 if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( sal_False ).nNode.GetIndex() ) 391 { 392 xub_StrLen nCntPos = pPam->GetBound( sal_False ).nContent.GetIndex(); 393 pPam->GetBound( sal_False ).nContent.Assign( pTxtNode, 394 pTxtNode->GetTxt().Len() + nCntPos ); 395 } 396 #endif 397 // Zeichen Attribute beibehalten! 398 SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode(); 399 if( pTxtNode->GetTxt().Len() ) 400 pDelNd->FmtToTxtAttr( pTxtNode ); 401 else 402 pTxtNode->ChgFmtColl( pDelNd->GetTxtColl() ); 403 pTxtNode->JoinNext(); 404 } 405 } 406 407 if( SVPAR_ACCEPTED == eState ) 408 { 409 // den letzen Bereich wieder zumachen 410 if( pRegionEndIdx ) 411 { 412 // JP 06.01.00: Task 71411 - the last section in WW are not a 413 // balanced Section. 414 if( !GetVersionNo() ) 415 { 416 SwSectionNode* pSectNd = pRegionEndIdx->GetNode(). 417 StartOfSectionNode()->GetSectionNode(); 418 if( pSectNd ) 419 pSectNd->GetSection().GetFmt()->SetFmtAttr( 420 SwFmtNoBalancedColumns( sal_True ) ); 421 } 422 423 DelLastNode(); 424 pPam->GetPoint()->nNode = *pRegionEndIdx; 425 pPam->Move( fnMoveForward, fnGoNode ); 426 delete pRegionEndIdx, pRegionEndIdx = 0; 427 } 428 429 sal_uInt16 nPageDescOffset = pDoc->GetPageDescCnt(); 430 maSegments.InsertSegments(IsNewDoc()); 431 UpdatePageDescs(*pDoc, nPageDescOffset); 432 //$flr folloing garbe collecting code has been moved from the previous procedure 433 // UpdatePageDescs to here in order to fix bug #117882# 434 rtfSections::myrDummyIter aDEnd = maSegments.maDummyPageNos.rend(); 435 for (rtfSections::myrDummyIter aI = maSegments.maDummyPageNos.rbegin(); aI != aDEnd; ++aI) 436 pDoc->DelPageDesc(*aI); 437 438 if( aFlyArr.Count() ) 439 SetFlysInDoc(); 440 441 // jetzt noch den letzten ueberfluessigen Absatz loeschen 442 SwPosition* pPos = pPam->GetPoint(); 443 if( !pPos->nContent.GetIndex() ) 444 { 445 SwTxtNode* pAktNd; 446 sal_uLong nNodeIdx = pPos->nNode.GetIndex(); 447 if( IsNewDoc() ) 448 { 449 SwNode* pTmp = pDoc->GetNodes()[ nNodeIdx -1 ]; 450 if( pTmp->IsCntntNode() && !pTmp->FindTableNode() ) 451 { 452 // --> FME 2006-02-15 #131200# Do not delete the paragraph 453 // if it has anchored objects: 454 bool bAnchoredObjs = false; 455 const SwSpzFrmFmts* pFrmFmts = pDoc->GetSpzFrmFmts(); 456 if ( pFrmFmts && pFrmFmts->Count() ) 457 { 458 for ( sal_uInt16 nI = pFrmFmts->Count(); nI; --nI ) 459 { 460 const SwFmtAnchor & rAnchor = (*pFrmFmts)[ nI - 1 ]->GetAnchor(); 461 if ((FLY_AT_PARA == rAnchor.GetAnchorId()) || 462 (FLY_AT_CHAR == rAnchor.GetAnchorId())) 463 { 464 const SwPosition * pObjPos = rAnchor.GetCntntAnchor(); 465 if ( pObjPos && nNodeIdx == pObjPos->nNode.GetIndex() ) 466 { 467 bAnchoredObjs = true; 468 break; 469 } 470 } 471 } 472 } 473 // <-- 474 475 if ( !bAnchoredObjs ) 476 DelLastNode(); 477 } 478 } 479 else if (0 != (pAktNd = pDoc->GetNodes()[nNodeIdx]->GetTxtNode())) 480 { 481 if( pAktNd->CanJoinNext( &pPos->nNode )) 482 { 483 SwTxtNode* pNextNd = pPos->nNode.GetNode().GetTxtNode(); 484 pPos->nContent.Assign( pNextNd, 0 ); 485 pPam->SetMark(); pPam->DeleteMark(); 486 pNextNd->JoinPrev(); 487 } 488 else if( !pAktNd->GetTxt().Len() && 489 pAktNd->StartOfSectionIndex()+2 < 490 pAktNd->EndOfSectionIndex() ) 491 { 492 pPos->nContent.Assign( 0, 0 ); 493 pPam->SetMark(); pPam->DeleteMark(); 494 pDoc->GetNodes().Delete( pPos->nNode, 1 ); 495 pPam->Move( fnMoveBackward ); 496 } 497 } 498 } 499 // nun noch das SplitNode vom Ende aufheben 500 else if( !IsNewDoc() ) 501 { 502 if( pPos->nContent.GetIndex() ) // dann gabs am Ende kein \par, 503 pPam->Move( fnMoveForward, fnGoNode ); // als zum naechsten Node 504 SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode(); 505 SwNodeIndex aPrvIdx( pPos->nNode ); 506 if( pTxtNode && pTxtNode->CanJoinPrev( &aPrvIdx ) && 507 *pSttNdIdx <= aPrvIdx ) 508 { 509 // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor 510 // usw. sind im pTxtNode angemeldet, so dass der bestehen 511 // bleiben MUSS. 512 513 // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die 514 // Absatzattribute und die Vorlage uebernehmen! 515 SwTxtNode* pPrev = aPrvIdx.GetNode().GetTxtNode(); 516 pTxtNode->ChgFmtColl( pPrev->GetTxtColl() ); 517 pTxtNode->FmtToTxtAttr( pPrev ); 518 pTxtNode->ResetAllAttr(); 519 520 if( pPrev->HasSwAttrSet() ) 521 pTxtNode->SetAttr( *pPrev->GetpSwAttrSet() ); 522 523 if( &pPam->GetBound(sal_True).nNode.GetNode() == pPrev ) 524 pPam->GetBound(sal_True).nContent.Assign( pTxtNode, 0 ); 525 if( &pPam->GetBound(sal_False).nNode.GetNode() == pPrev ) 526 pPam->GetBound(sal_False).nContent.Assign( pTxtNode, 0 ); 527 528 pTxtNode->JoinPrev(); 529 } 530 } 531 } 532 delete pSttNdIdx, pSttNdIdx = 0; 533 delete pRegionEndIdx, pRegionEndIdx = 0; 534 RemoveUnusedNumRules(); 535 536 pDoc->SetUpdateExpFldStat(true); 537 pDoc->SetInitDBFields(true); 538 539 // Laufbalken bei asynchronen Call nicht einschalten !!! 540 ::EndProgress( pDoc->GetDocShell() ); 541 } 542 543 bool rtfSections::SetCols(SwFrmFmt &rFmt, const rtfSection &rSection, 544 sal_uInt16 nNettoWidth) 545 { 546 //sprmSCcolumns - Anzahl der Spalten - 1 547 sal_uInt16 nCols = static_cast< sal_uInt16 >(rSection.NoCols()); 548 549 if (nCols < 2) 550 return false; // keine oder bloedsinnige Spalten 551 552 SwFmtCol aCol; // Erzeuge SwFmtCol 553 554 //sprmSDxaColumns - Default-Abstand 1.25 cm 555 sal_uInt16 nColSpace = static_cast< sal_uInt16 >(rSection.StandardColSeperation()); 556 557 aCol.Init( nCols, nColSpace, nNettoWidth ); 558 559 // not SFEvenlySpaced 560 if (rSection.maPageInfo.maColumns.size()) 561 { 562 aCol._SetOrtho(false); 563 sal_uInt16 nWishWidth = 0, nHalfPrev = 0; 564 for (sal_uInt16 n=0, i=0; 565 (static_cast<size_t>(n)+1) < rSection.maPageInfo.maColumns.size() && i < nCols; 566 n += 2, ++i) 567 { 568 SwColumn* pCol = aCol.GetColumns()[ i ]; 569 pCol->SetLeft( nHalfPrev ); 570 sal_uInt16 nSp = static_cast< sal_uInt16 >(rSection.maPageInfo.maColumns[ n+1 ]); 571 nHalfPrev = nSp / 2; 572 pCol->SetRight( nSp - nHalfPrev ); 573 pCol->SetWishWidth( static_cast< sal_uInt16 >(rSection.maPageInfo.maColumns[ n ]) + 574 pCol->GetLeft() + pCol->GetRight()); 575 nWishWidth = nWishWidth + pCol->GetWishWidth(); 576 } 577 aCol.SetWishWidth( nWishWidth ); 578 } 579 580 rFmt.SetFmtAttr(aCol); 581 return true; 582 } 583 584 void rtfSections::SetPage(SwPageDesc &rInPageDesc, SwFrmFmt &rFmt, 585 const rtfSection &rSection, bool bIgnoreCols) 586 { 587 // 1. Orientierung 588 rInPageDesc.SetLandscape(rSection.IsLandScape()); 589 590 // 2. Papiergroesse 591 SwFmtFrmSize aSz(rFmt.GetFrmSize()); 592 aSz.SetWidth(rSection.GetPageWidth()); 593 aSz.SetHeight(rSection.GetPageHeight()); 594 rFmt.SetFmtAttr(aSz); 595 596 rFmt.SetFmtAttr( 597 SvxLRSpaceItem(rSection.GetPageLeft(), rSection.GetPageRight(), 0, 0, RES_LR_SPACE)); 598 599 if (!bIgnoreCols) 600 { 601 SetCols(rFmt, rSection, static_cast< sal_uInt16 >(rSection.GetPageWidth() - 602 rSection.GetPageLeft() - rSection.GetPageRight())); 603 } 604 605 rFmt.SetFmtAttr(rSection.maPageInfo.maBox); 606 } 607 608 bool HasHeader(const SwFrmFmt &rFmt) 609 { 610 const SfxPoolItem *pHd; 611 if (SFX_ITEM_SET == rFmt.GetItemState(RES_HEADER, false, &pHd)) 612 return ((const SwFmtHeader *)(pHd))->IsActive(); 613 return false; 614 } 615 616 bool HasFooter(const SwFrmFmt &rFmt) 617 { 618 const SfxPoolItem *pFt; 619 if (SFX_ITEM_SET == rFmt.GetItemState(RES_FOOTER, false, &pFt)) 620 return ((const SwFmtFooter *)(pFt))->IsActive(); 621 return false; 622 } 623 624 void rtfSections::GetPageULData(const rtfSection &rSection, bool bFirst, 625 rtfSections::wwULSpaceData& rData) 626 { 627 short nWWUp = static_cast< short >(rSection.maPageInfo.mnMargtsxn); 628 short nWWLo = static_cast< short >(rSection.maPageInfo.mnMargbsxn); 629 short nWWHTop = static_cast< short >(rSection.maPageInfo.mnHeadery); 630 short nWWFBot = static_cast< short >(rSection.maPageInfo.mnFootery); 631 632 if (bFirst) 633 { 634 if ( 635 rSection.mpTitlePage && HasHeader(rSection.mpTitlePage->GetMaster()) 636 ) 637 { 638 rData.bHasHeader = true; 639 } 640 } 641 else 642 { 643 if (rSection.mpPage && 644 ( 645 HasHeader(rSection.mpPage->GetMaster()) 646 || HasHeader(rSection.mpPage->GetLeft()) 647 ) 648 ) 649 { 650 rData.bHasHeader = true; 651 } 652 } 653 654 if( rData.bHasHeader ) 655 { 656 rData.nSwUp = nWWHTop; // Header -> umrechnen, see ww8par6.cxx 657 658 if ( nWWUp > 0 && nWWUp >= nWWHTop ) 659 rData.nSwHLo = nWWUp - nWWHTop; 660 else 661 rData.nSwHLo = 0; 662 663 if (rData.nSwHLo < cMinHdFtHeight) 664 rData.nSwHLo = cMinHdFtHeight; 665 } 666 else // kein Header -> Up einfach uebernehmen 667 rData.nSwUp = Abs(nWWUp); 668 669 if (bFirst) 670 { 671 if ( 672 rSection.mpTitlePage && 673 HasFooter(rSection.mpTitlePage->GetMaster()) 674 ) 675 { 676 rData.bHasFooter = true; 677 } 678 } 679 else 680 { 681 if (rSection.mpPage && 682 ( 683 HasFooter(rSection.mpPage->GetMaster()) 684 || HasFooter(rSection.mpPage->GetLeft()) 685 ) 686 ) 687 { 688 rData.bHasFooter = true; 689 } 690 } 691 692 if( rData.bHasFooter ) 693 { 694 rData.nSwLo = nWWFBot; // Footer -> Umrechnen 695 if ( nWWLo > 0 && nWWLo >= nWWFBot ) 696 rData.nSwFUp = nWWLo - nWWFBot; 697 else 698 rData.nSwFUp = 0; 699 700 if (rData.nSwFUp < cMinHdFtHeight) 701 rData.nSwFUp = cMinHdFtHeight; 702 } 703 else // kein Footer -> Lo einfach uebernehmen 704 rData.nSwLo = Abs(nWWLo); 705 } 706 707 void rtfSections::SetPageULSpaceItems(SwFrmFmt &rFmt, 708 rtfSections::wwULSpaceData& rData) 709 { 710 if (rData.bHasHeader) // ... und Header-Lower setzen 711 { 712 //Kopfzeilenhoehe minimal sezten 713 if (SwFrmFmt* pHdFmt = (SwFrmFmt*)rFmt.GetHeader().GetHeaderFmt()) 714 { 715 pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwHLo)); 716 SvxULSpaceItem aHdUL(pHdFmt->GetULSpace()); 717 aHdUL.SetLower( rData.nSwHLo - cMinHdFtHeight ); 718 pHdFmt->SetFmtAttr(aHdUL); 719 pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem( 720 RES_HEADER_FOOTER_EAT_SPACING, true)); 721 } 722 } 723 724 if (rData.bHasFooter) // ... und Footer-Upper setzen 725 { 726 if (SwFrmFmt* pFtFmt = (SwFrmFmt*)rFmt.GetFooter().GetFooterFmt()) 727 { 728 pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwFUp)); 729 SvxULSpaceItem aFtUL(pFtFmt->GetULSpace()); 730 aFtUL.SetUpper( rData.nSwFUp - cMinHdFtHeight ); 731 pFtFmt->SetFmtAttr(aFtUL); 732 pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem( 733 RES_HEADER_FOOTER_EAT_SPACING, true)); 734 } 735 } 736 737 SvxULSpaceItem aUL(rData.nSwUp, rData.nSwLo, RES_UL_SPACE ); // Page-UL setzen 738 rFmt.SetFmtAttr(aUL); 739 } 740 741 void rtfSections::SetSegmentToPageDesc(const rtfSection &rSection, 742 bool bTitlePage, bool bIgnoreCols) 743 { 744 SwPageDesc &rPage = bTitlePage ? *rSection.mpTitlePage : *rSection.mpPage; 745 746 // SetNumberingType(rSection, rPage); 747 748 SwFrmFmt &rFmt = rPage.GetMaster(); 749 // mrReader.SetDocumentGrid(rFmt, rSection); 750 751 wwULSpaceData aULData; 752 GetPageULData(rSection, bTitlePage, aULData); 753 SetPageULSpaceItems(rFmt, aULData); 754 755 SetPage(rPage, rFmt, rSection, bIgnoreCols); 756 757 UseOnPage ePage = rPage.ReadUseOn(); 758 if(ePage & nsUseOnPage::PD_ALL) 759 { 760 SwFrmFmt &rFmtLeft = rPage.GetLeft(); 761 SetPageULSpaceItems(rFmtLeft, aULData); 762 SetPage(rPage, rFmtLeft, rSection, bIgnoreCols); 763 } 764 765 } 766 767 void rtfSections::CopyFrom(const SwPageDesc &rFrom, SwPageDesc &rDest) 768 { 769 UseOnPage ePage = rFrom.ReadUseOn(); 770 rDest.WriteUseOn(ePage); 771 772 mrReader.pDoc->CopyHeader(rFrom.GetMaster(), rDest.GetMaster()); 773 SwFrmFmt &rDestFmt = rDest.GetMaster(); 774 rDestFmt.SetFmtAttr(rFrom.GetMaster().GetHeader()); 775 mrReader.pDoc->CopyHeader(rFrom.GetLeft(), rDest.GetLeft()); 776 mrReader.pDoc->CopyFooter(rFrom.GetMaster(), rDest.GetMaster()); 777 mrReader.pDoc->CopyFooter(rFrom.GetLeft(), rDest.GetLeft()); 778 } 779 780 void rtfSections::MoveFrom(SwPageDesc &rFrom, SwPageDesc &rDest) 781 { 782 UseOnPage ePage = rFrom.ReadUseOn(); 783 rDest.WriteUseOn(ePage); 784 785 SwFrmFmt &rDestMaster = rDest.GetMaster(); 786 SwFrmFmt &rFromMaster = rFrom.GetMaster(); 787 rDestMaster.SetFmtAttr(rFromMaster.GetHeader()); 788 rDestMaster.SetFmtAttr(rFromMaster.GetFooter()); 789 //rFromMaster.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882# 790 //rFromMaster.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882# 791 792 SwFrmFmt &rDestLeft = rDest.GetLeft(); 793 SwFrmFmt &rFromLeft = rFrom.GetLeft(); 794 rDestLeft.SetFmtAttr(rFromLeft.GetHeader()); 795 rDestLeft.SetFmtAttr(rFromLeft.GetFooter()); 796 //rFromLeft.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882# 797 //rFromLeft.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882# 798 } 799 800 void rtfSections::SetHdFt(rtfSection &rSection) 801 { 802 ASSERT(rSection.mpPage, "makes no sense to call without a main page"); 803 if (rSection.mpPage && rSection.maPageInfo.mpPageHdFt) 804 { 805 if (rSection.maPageInfo.mbPageHdFtUsed) 806 { 807 MoveFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage); 808 rSection.maPageInfo.mbPageHdFtUsed = false; 809 rSection.maPageInfo.mpPageHdFt = rSection.mpPage; 810 } 811 else 812 CopyFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage); 813 } 814 815 if (rSection.mpTitlePage && rSection.maPageInfo.mpTitlePageHdFt) 816 { 817 if (rSection.maPageInfo.mbTitlePageHdFtUsed) 818 { 819 MoveFrom(*rSection.maPageInfo.mpTitlePageHdFt, 820 *rSection.mpTitlePage); 821 rSection.maPageInfo.mbTitlePageHdFtUsed = false; 822 rSection.maPageInfo.mpTitlePageHdFt = rSection.mpTitlePage; 823 } 824 else 825 { 826 CopyFrom(*rSection.maPageInfo.mpTitlePageHdFt, 827 *rSection.mpTitlePage); 828 } 829 } 830 } 831 832 SwSectionFmt *rtfSections::InsertSection(SwPaM& rMyPaM, rtfSection &rSection) 833 { 834 SwSectionData aSectionData(CONTENT_SECTION, 835 mrReader.pDoc->GetUniqueSectionName()); 836 837 SfxItemSet aSet( mrReader.pDoc->GetAttrPool(), aFrmFmtSetRange ); 838 839 sal_uInt8 nRTLPgn = maSegments.empty() ? 0 : maSegments.back().IsBiDi(); 840 aSet.Put(SvxFrameDirectionItem( 841 nRTLPgn ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR)); 842 843 rSection.mpSection = 844 mrReader.pDoc->InsertSwSection( rMyPaM, aSectionData, 0, &aSet ); 845 ASSERT(rSection.mpSection, "section not inserted!"); 846 if (!rSection.mpSection) 847 return 0; 848 849 SwPageDesc *pPage = 0; 850 mySegrIter aEnd = maSegments.rend(); 851 for (mySegrIter aIter = maSegments.rbegin(); aIter != aEnd; ++aIter) 852 { 853 pPage = aIter->mpPage; 854 if (pPage) 855 break; 856 } 857 858 ASSERT(pPage, "no page outside this section!"); 859 860 if (!pPage) 861 pPage = &mrReader.pDoc->_GetPageDesc(0); 862 863 if (!pPage) 864 return 0; 865 866 SwFrmFmt& rFmt = pPage->GetMaster(); 867 const SwFmtFrmSize& rSz = rFmt.GetFrmSize(); 868 const SvxLRSpaceItem& rLR = rFmt.GetLRSpace(); 869 SwTwips nWidth = rSz.GetWidth(); 870 long nLeft = rLR.GetTxtLeft(); 871 long nRight = rLR.GetRight(); 872 873 SwSectionFmt *pFmt = rSection.mpSection->GetFmt(); 874 ASSERT(pFmt, "impossible"); 875 if (!pFmt) 876 return 0; 877 SetCols(*pFmt, rSection, (sal_uInt16)(nWidth - nLeft - nRight) ); 878 879 return pFmt; 880 } 881 882 void rtfSections::InsertSegments(bool bNewDoc) 883 { 884 sal_uInt16 nDesc(0); 885 mySegIter aEnd = maSegments.end(); 886 mySegIter aStart = maSegments.begin(); 887 for (mySegIter aIter = aStart; aIter != aEnd; ++aIter) 888 { 889 mySegIter aNext = aIter+1; 890 891 bool bInsertSection = aIter != aStart ? aIter->IsContinous() : false; 892 893 if (!bInsertSection) 894 { 895 /* 896 If a cont section follow this section then we won't be 897 creating a page desc with 2+ cols as we cannot host a one 898 col section in a 2+ col pagedesc and make it look like 899 word. But if the current section actually has columns then 900 we are forced to insert a section here as well as a page 901 descriptor. 902 */ 903 904 /* 905 Note for the future: 906 If we want to import "protected sections" the here is 907 where we would also test for that and force a section 908 insertion if that was true. 909 */ 910 bool bIgnoreCols = false; 911 if (aNext != aEnd && aNext->IsContinous()) 912 { 913 bIgnoreCols = true; 914 if (aIter->NoCols() > 1) 915 bInsertSection = true; 916 } 917 918 if (aIter->HasTitlePage()) 919 { 920 if (bNewDoc && aIter == aStart) 921 { 922 aIter->mpTitlePage = 923 mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_FIRST); 924 } 925 else 926 { 927 sal_uInt16 nPos = mrReader.pDoc->MakePageDesc( 928 ViewShell::GetShellRes()->GetPageDescName(nDesc) 929 , 0, false); 930 aIter->mpTitlePage = &mrReader.pDoc->_GetPageDesc(nPos); 931 } 932 ASSERT(aIter->mpTitlePage, "no page!"); 933 if (!aIter->mpTitlePage) 934 continue; 935 936 SetSegmentToPageDesc(*aIter, true, bIgnoreCols); 937 } 938 939 if (!bNewDoc && aIter == aStart) 940 continue; 941 else if (bNewDoc && aIter == aStart) 942 { 943 aIter->mpPage = 944 mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_STANDARD); 945 } 946 else 947 { 948 sal_uInt16 nPos = mrReader.pDoc->MakePageDesc( 949 ViewShell::GetShellRes()->GetPageDescName(nDesc, 950 false, aIter->HasTitlePage()), 951 aIter->mpTitlePage, false); 952 aIter->mpPage = &mrReader.pDoc->_GetPageDesc(nPos); 953 } 954 ASSERT(aIter->mpPage, "no page!"); 955 if (!aIter->mpPage) 956 continue; 957 958 SetHdFt(*aIter); 959 960 if (aIter->mpTitlePage) 961 SetSegmentToPageDesc(*aIter, true, bIgnoreCols); 962 SetSegmentToPageDesc(*aIter, false, bIgnoreCols); 963 964 SwFmtPageDesc aPgDesc(aIter->HasTitlePage() ? 965 aIter->mpTitlePage : aIter->mpPage); 966 967 if (aIter->mpTitlePage) 968 aIter->mpTitlePage->SetFollow(aIter->mpPage); 969 970 if (aIter->PageRestartNo() || 971 ((aIter == aStart) && aIter->PageStartAt() != 1)) 972 aPgDesc.SetNumOffset( static_cast< sal_uInt16 >(aIter->PageStartAt()) ); 973 974 /* 975 If its a table here, apply the pagebreak to the table 976 properties, otherwise we add it to the para at this 977 position 978 */ 979 if (aIter->maStart.GetNode().IsTableNode()) 980 { 981 SwTable& rTable = 982 aIter->maStart.GetNode().GetTableNode()->GetTable(); 983 SwFrmFmt* pApply = rTable.GetFrmFmt(); 984 ASSERT(pApply, "impossible"); 985 if (pApply) 986 pApply->SetFmtAttr(aPgDesc); 987 } 988 else 989 { 990 SwPosition aPamStart(aIter->maStart); 991 aPamStart.nContent.Assign( 992 aIter->maStart.GetNode().GetCntntNode(), 0); 993 SwPaM aPage(aPamStart); 994 995 mrReader.pDoc->InsertPoolItem(aPage, aPgDesc, 0); 996 } 997 ++nDesc; 998 } 999 1000 SwTxtNode* pTxtNd = 0; 1001 if (bInsertSection) 1002 { 1003 SwPaM aSectPaM(*mrReader.pPam); 1004 SwNodeIndex aAnchor(aSectPaM.GetPoint()->nNode); 1005 if (aNext != aEnd) 1006 { 1007 aAnchor = aNext->maStart; 1008 aSectPaM.GetPoint()->nNode = aAnchor; 1009 aSectPaM.GetPoint()->nContent.Assign( 1010 aNext->maStart.GetNode().GetCntntNode(), 0); 1011 aSectPaM.Move(fnMoveBackward); 1012 } 1013 1014 const SwPosition* pPos = aSectPaM.GetPoint(); 1015 SwTxtNode const*const pSttNd = pPos->nNode.GetNode().GetTxtNode(); 1016 const SwTableNode* pTableNd = pSttNd ? pSttNd->FindTableNode() : 0; 1017 if (pTableNd) 1018 { 1019 pTxtNd = 1020 mrReader.pDoc->GetNodes().MakeTxtNode(aAnchor, 1021 mrReader.pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT )); 1022 1023 aSectPaM.GetPoint()->nNode = SwNodeIndex(*pTxtNd); 1024 aSectPaM.GetPoint()->nContent.Assign( 1025 aSectPaM.GetCntntNode(), 0); 1026 } 1027 1028 aSectPaM.SetMark(); 1029 1030 aSectPaM.GetPoint()->nNode = aIter->maStart; 1031 aSectPaM.GetPoint()->nContent.Assign( 1032 aSectPaM.GetCntntNode(), 0); 1033 1034 SwSectionFmt *pRet = InsertSection(aSectPaM, *aIter); 1035 //The last section if continous is always unbalanced 1036 if (aNext == aEnd && pRet) 1037 pRet->SetFmtAttr(SwFmtNoBalancedColumns(true)); 1038 } 1039 1040 if (pTxtNd) 1041 { 1042 SwNodeIndex aIdx(*pTxtNd); 1043 SwPosition aPos(aIdx); 1044 SwPaM aTest(aPos); 1045 mrReader.pDoc->DelFullPara(aTest); 1046 pTxtNd = 0; 1047 } 1048 } 1049 } 1050 1051 namespace sw{ 1052 namespace util{ 1053 1054 InsertedTableClient::InsertedTableClient(SwTableNode & rNode) 1055 { 1056 rNode.Add(this); 1057 } 1058 1059 SwTableNode * InsertedTableClient::GetTableNode() 1060 { 1061 return dynamic_cast<SwTableNode *> (GetRegisteredInNonConst()); 1062 } 1063 1064 InsertedTablesManager::InsertedTablesManager(const SwDoc &rDoc) 1065 : mbHasRoot(rDoc.GetCurrentLayout()) //swmod 080218 1066 { 1067 } 1068 1069 void InsertedTablesManager::DelAndMakeTblFrms() 1070 { 1071 if (!mbHasRoot) 1072 return; 1073 TblMapIter aEnd = maTables.end(); 1074 for (TblMapIter aIter = maTables.begin(); aIter != aEnd; ++aIter) 1075 { 1076 // exitiert schon ein Layout, dann muss an dieser Tabelle die BoxFrames 1077 // neu erzeugt 1078 SwTableNode *pTable = aIter->first->GetTableNode(); 1079 ASSERT(pTable, "Why no expected table"); 1080 if (pTable) 1081 { 1082 SwFrmFmt * pFrmFmt = pTable->GetTable().GetFrmFmt(); 1083 1084 if (pFrmFmt != NULL) 1085 { 1086 SwNodeIndex *pIndex = aIter->second; 1087 pTable->DelFrms(); 1088 pTable->MakeFrms(pIndex); 1089 } 1090 } 1091 } 1092 } 1093 1094 void InsertedTablesManager::InsertTable(SwTableNode &rTableNode, SwPaM &rPaM) 1095 { 1096 if (!mbHasRoot) 1097 return; 1098 //Associate this tablenode with this after position, replace an //old 1099 //node association if necessary 1100 1101 InsertedTableClient * pClient = new InsertedTableClient(rTableNode); 1102 1103 maTables.insert(TblMap::value_type(pClient, &(rPaM.GetPoint()->nNode))); 1104 } 1105 } 1106 } 1107 1108 SwRTFParser::~SwRTFParser() 1109 { 1110 maInsertedTables.DelAndMakeTblFrms(); 1111 mpRedlineStack->closeall(*pPam->GetPoint()); 1112 delete mpRedlineStack; 1113 1114 delete pSttNdIdx; 1115 delete pRegionEndIdx; 1116 delete pPam; 1117 delete pRelNumRule; 1118 1119 if (aFlyArr.Count()) 1120 aFlyArr.DeleteAndDestroy( 0, aFlyArr.Count() ); 1121 1122 if (pGrfAttrSet) 1123 DELETEZ( pGrfAttrSet ); 1124 1125 DELETEZ( pAuthorInfos ); 1126 } 1127 1128 //i19718 1129 void SwRTFParser::ReadShpRslt() 1130 { 1131 int nToken; 1132 while ('}' != (nToken = GetNextToken() ) && IsParserWorking()) 1133 { 1134 switch(nToken) 1135 { 1136 case RTF_PAR: 1137 break; 1138 default: 1139 NextToken(nToken); 1140 break; 1141 } 1142 } 1143 SkipToken(-1); 1144 } 1145 1146 void SwRTFParser::ReadShpTxt(String& s) 1147 { 1148 int nToken; 1149 int level=1; 1150 s.AppendAscii("{\\rtf"); 1151 while (level>0 && IsParserWorking()) 1152 { 1153 nToken = GetNextToken(); 1154 switch(nToken) 1155 { 1156 case RTF_SN: 1157 case RTF_SV: 1158 SkipGroup(); 1159 break; 1160 case RTF_TEXTTOKEN: 1161 s.Append(aToken); 1162 break; 1163 case '{': 1164 level++; 1165 s.Append(String::CreateFromAscii("{")); 1166 break; 1167 case '}': 1168 level--; 1169 s.Append(String::CreateFromAscii("}")); 1170 break; 1171 default: 1172 s.Append(aToken); 1173 if (bTokenHasValue) { 1174 s.Append(String::CreateFromInt64(nTokenValue)); 1175 } 1176 s.Append(String::CreateFromAscii(" ")); 1177 break; 1178 } 1179 } 1180 SkipToken(-1); 1181 } 1182 1183 /* 1184 * #127429#. Very basic support for the "Buchhalternase". 1185 */ 1186 void SwRTFParser::ReadDrawingObject() 1187 { 1188 int nToken; 1189 int level; 1190 level=1; 1191 Rectangle aRect; 1192 ::basegfx::B2DPolygon aPolygon; 1193 ::basegfx::B2DPoint aPoint; 1194 bool bPolygonActive(false); 1195 1196 while (level>0 && IsParserWorking()) 1197 { 1198 nToken = GetNextToken(); 1199 switch(nToken) 1200 { 1201 case '}': 1202 level--; 1203 break; 1204 case '{': 1205 level++; 1206 break; 1207 case RTF_DPX: 1208 aRect.setX(nTokenValue); 1209 break; 1210 case RTF_DPXSIZE: 1211 aRect.setWidth(nTokenValue); 1212 break; 1213 case RTF_DPY: 1214 aRect.setY(nTokenValue); 1215 break; 1216 case RTF_DPYSIZE: 1217 aRect.setHeight(nTokenValue); 1218 break; 1219 case RTF_DPPOLYCOUNT: 1220 bPolygonActive = true; 1221 break; 1222 case RTF_DPPTX: 1223 aPoint.setX(nTokenValue); 1224 break; 1225 case RTF_DPPTY: 1226 aPoint.setY(nTokenValue); 1227 1228 if(bPolygonActive) 1229 { 1230 aPolygon.append(aPoint); 1231 } 1232 1233 break; 1234 default: 1235 break; 1236 } 1237 } 1238 SkipToken(-1); 1239 /* 1240 const Point aPointC1( 0, 0 ); 1241 const Point aPointC2( 100, 200 ); 1242 const Point aPointC3( 300, 400 ); 1243 XPolygon aPolygonC(3); 1244 aPolygonC[0] = aPointC1; 1245 aPolygonC[1] = aPointC2; 1246 aPolygonC[2] = aPointC3; 1247 */ 1248 if(bPolygonActive && aPolygon.count()) 1249 { 1250 SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aPolygon)); 1251 SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1); 1252 SwFmtSurround aSur( SURROUND_PARALLEL ); 1253 aSur.SetContour( false ); 1254 aSur.SetOutside(true); 1255 aFlySet.Put( aSur ); 1256 SwFmtFollowTextFlow aFollowTextFlow( sal_False ); 1257 aFlySet.Put( aFollowTextFlow ); 1258 /* 1259 sw::util::SetLayer aSetLayer(*pDoc); 1260 aSetLayer.SendObjectToHeaven(*pStroke); 1261 */ 1262 SwFmtAnchor aAnchor( FLY_AT_PARA ); 1263 aAnchor.SetAnchor( pPam->GetPoint() ); 1264 aFlySet.Put( aAnchor ); 1265 1266 /* 1267 text::RelOrientation::FRAME, // Absatz inkl. Raender 1268 text::RelOrientation::PRINT_AREA, // Absatz ohne Raender 1269 text::RelOrientation::CHAR, // an einem Zeichen 1270 text::RelOrientation::PAGE_LEFT, // im linken Seitenrand 1271 text::RelOrientation::PAGE_RIGHT, // im rechten Seitenrand 1272 text::RelOrientation::FRAME_LEFT, // im linken Absatzrand 1273 text::RelOrientation::FRAME_RIGHT, // im rechten Absatzrand 1274 text::RelOrientation::PAGE_FRAME, // Seite inkl. Raender, bei seitengeb. identisch mit text::RelOrientation::FRAME 1275 text::RelOrientation::PAGE_PRINT_AREA, // Seite ohne Raender, bei seitengeb. identisch mit text::RelOrientation::PRTAREA 1276 // OD 11.11.2003 #i22341# 1277 text::RelOrientation::TEXT_LINE, // vertical relative to top of text line, only for to-character 1278 // anchored objects. 1279 1280 1281 text::HoriOrientation::NONE, //Der Wert in nYPos gibt die RelPos direkt an. 1282 text::HoriOrientation::RIGHT, //Der Rest ist fuer automatische Ausrichtung. 1283 text::HoriOrientation::CENTER, 1284 text::HoriOrientation::LEFT, 1285 text::HoriOrientation::INSIDE, 1286 text::HoriOrientation::OUTSIDE, 1287 text::HoriOrientation::FULL, //Spezialwert fuer Tabellen 1288 text::HoriOrientation::LEFT_AND_WIDTH //Auch fuer Tabellen 1289 */ 1290 SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ); 1291 aFlySet.Put( aHori ); 1292 /* 1293 text::VertOrientation::NONE, //Der Wert in nYPos gibt die RelPos direkt an. 1294 text::VertOrientation::TOP, //Der Rest ist fuer automatische Ausrichtung. 1295 text::VertOrientation::CENTER, 1296 text::VertOrientation::BOTTOM, 1297 text::VertOrientation::CHAR_TOP, //Ausrichtung _nur_ fuer Zeichengebundene Rahmen 1298 text::VertOrientation::CHAR_CENTER, //wie der Name jew. sagt wird der RefPoint des Rahmens 1299 text::VertOrientation::CHAR_BOTTOM, //entsprechend auf die Oberkante, Mitte oder Unterkante 1300 text::VertOrientation::LINE_TOP, //der Zeile gesetzt. Der Rahmen richtet sich dann 1301 text::VertOrientation::LINE_CENTER, //entsprechend aus. 1302 text::VertOrientation::LINE_BOTTOM 1303 */ 1304 SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ); 1305 aFlySet.Put( aVert ); 1306 1307 pDoc->GetOrCreateDrawModel(); 1308 SdrModel* pDrawModel = pDoc->GetDrawModel(); 1309 SdrPage* pDrawPg = pDrawModel->GetPage(0); 1310 pDrawPg->InsertObject(pStroke, 0); 1311 1312 pStroke->SetSnapRect(aRect); 1313 1314 /* SwFrmFmt* pRetFrmFmt = */pDoc->InsertDrawObj(*pPam, *pStroke, aFlySet ); 1315 } 1316 } 1317 1318 void SwRTFParser::InsertShpObject(SdrObject* pStroke, int _nZOrder) 1319 { 1320 SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1); 1321 SwFmtSurround aSur( SURROUND_THROUGHT ); 1322 aSur.SetContour( false ); 1323 aSur.SetOutside(true); 1324 aFlySet.Put( aSur ); 1325 SwFmtFollowTextFlow aFollowTextFlow( sal_False ); 1326 aFlySet.Put( aFollowTextFlow ); 1327 1328 SwFmtAnchor aAnchor( FLY_AT_PARA ); 1329 aAnchor.SetAnchor( pPam->GetPoint() ); 1330 aFlySet.Put( aAnchor ); 1331 1332 1333 SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ); 1334 aFlySet.Put( aHori ); 1335 1336 SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ); 1337 aFlySet.Put( aVert ); 1338 1339 aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false)); 1340 1341 pDoc->GetOrCreateDrawModel(); 1342 SdrModel* pDrawModel = pDoc->GetDrawModel(); 1343 SdrPage* pDrawPg = pDrawModel->GetPage(0); 1344 pDrawPg->InsertObject(pStroke); 1345 pDrawPg->SetObjectOrdNum(pStroke->GetOrdNum(), _nZOrder); 1346 /* SwFrmFmt* pRetFrmFmt = */pDoc->InsertDrawObj(*pPam, *pStroke, aFlySet ); 1347 } 1348 1349 ::basegfx::B2DPoint rotate(const ::basegfx::B2DPoint& rStart, const ::basegfx::B2DPoint& rEnd) 1350 { 1351 const ::basegfx::B2DVector aVector(rStart - rEnd); 1352 return ::basegfx::B2DPoint(aVector.getY() + rEnd.getX(), -aVector.getX() + rEnd.getY()); 1353 } 1354 1355 1356 void SwRTFParser::ReadShapeObject() 1357 { 1358 int nToken; 1359 int level; 1360 level=1; 1361 ::basegfx::B2DPoint aPointLeftTop; 1362 ::basegfx::B2DPoint aPointRightBottom; 1363 String sn; 1364 sal_Int32 shapeType=-1; 1365 Graphic aGrf; 1366 bool bGrfValid=false; 1367 bool fFilled=true; 1368 Color fillColor(255, 255, 255); 1369 bool fLine=true; 1370 int lineWidth=9525/360; 1371 String shpTxt; 1372 bool bshpTxt=false; 1373 int txflTextFlow=0; 1374 ::rtl::OUString sDescription, sName; 1375 1376 1377 while (level>0 && IsParserWorking()) 1378 { 1379 nToken = GetNextToken(); 1380 switch(nToken) 1381 { 1382 case '}': 1383 level--; 1384 break; 1385 case '{': 1386 level++; 1387 break; 1388 case RTF_SHPLEFT: 1389 aPointLeftTop.setX(nTokenValue); 1390 break; 1391 case RTF_SHPTOP: 1392 aPointLeftTop.setY(nTokenValue); 1393 break; 1394 case RTF_SHPBOTTOM: 1395 aPointRightBottom.setY(nTokenValue); 1396 break; 1397 case RTF_SHPRIGHT: 1398 aPointRightBottom.setX(nTokenValue); 1399 break; 1400 case RTF_SN: 1401 nToken = GetNextToken(); 1402 ASSERT(nToken==RTF_TEXTTOKEN, "expected name"); 1403 sn=aToken; 1404 break; 1405 case RTF_SV: 1406 nToken = GetNextToken(); 1407 if (nToken==RTF_TEXTTOKEN) 1408 { 1409 if (sn.EqualsAscii("shapeType")) 1410 { 1411 shapeType=aToken.ToInt32(); 1412 1413 } else if (sn.EqualsAscii("fFilled")) 1414 { 1415 fFilled=aToken.ToInt32(); 1416 1417 } else if (sn.EqualsAscii("fLine")) 1418 { 1419 fLine=aToken.ToInt32(); 1420 } else if (sn.EqualsAscii("lineWidth")) 1421 { 1422 lineWidth=aToken.ToInt32()/360; 1423 1424 } else if (sn.EqualsAscii("fillColor")) 1425 { 1426 sal_uInt32 nColor=aToken.ToInt32(); 1427 fillColor=Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) ); 1428 }else if (sn.EqualsAscii("txflTextFlow")) 1429 { 1430 txflTextFlow=aToken.ToInt32(); 1431 } 1432 else if (sn.EqualsAscii("wzDescription")) 1433 { 1434 sDescription = aToken; 1435 } 1436 else if(sn.EqualsAscii("wzName")) 1437 { 1438 sName = aToken; 1439 } 1440 } 1441 break; 1442 case RTF_PICT: 1443 { 1444 SvxRTFPictureType aPicType; 1445 bGrfValid=ReadBmpData( aGrf, aPicType ); 1446 } 1447 break; 1448 case RTF_SHPRSLT: 1449 if (shapeType!=1 && shapeType!=20 && shapeType!=75) 1450 { 1451 ReadShpRslt(); 1452 } 1453 break; 1454 case RTF_SHPTXT: 1455 ReadShpTxt(shpTxt); 1456 bshpTxt=true; 1457 break; 1458 1459 default: 1460 break; 1461 } 1462 } 1463 SkipToken(-1); 1464 1465 SdrObject* pSdrObject = 0; 1466 switch(shapeType) 1467 { 1468 case 202: /* Text Box */ 1469 case 1: /* Rectangle */ 1470 { 1471 ::basegfx::B2DRange aRange(aPointLeftTop); 1472 aRange.expand(aPointRightBottom); 1473 1474 if (txflTextFlow==2) { 1475 const ::basegfx::B2DPoint a(rotate(aRange.getMinimum(), aRange.getCenter())); 1476 const ::basegfx::B2DPoint b(rotate(aRange.getMaximum(), aRange.getCenter())); 1477 1478 aRange.reset(); 1479 aRange.expand(a); 1480 aRange.expand(b); 1481 } 1482 1483 const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY())); 1484 SdrRectObj* pStroke = new SdrRectObj(aRect); 1485 pSdrObject = pStroke; 1486 pStroke->SetSnapRect(aRect); 1487 pDoc->GetOrCreateDrawModel(); // create model 1488 InsertShpObject(pStroke, this->nZOrder++); 1489 SfxItemSet aSet(pStroke->GetMergedItemSet()); 1490 if (fFilled) 1491 { 1492 aSet.Put(XFillStyleItem(XFILL_SOLID)); 1493 aSet.Put(XFillColorItem( String(), fillColor ) ); 1494 } 1495 else 1496 { 1497 aSet.Put(XFillStyleItem(XFILL_NONE)); 1498 } 1499 if (!fLine) { 1500 aSet.Put(XLineStyleItem(XLINE_NONE)); 1501 } else { 1502 aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width 1503 } 1504 1505 pStroke->SetMergedItemSet(aSet); 1506 if (bshpTxt) { 1507 SdrOutliner& rOutliner=pDoc->GetDrawModel()->GetDrawOutliner(pStroke); 1508 rOutliner.Clear(); 1509 ByteString bs(shpTxt, RTL_TEXTENCODING_ASCII_US); 1510 SvMemoryStream aStream((sal_Char*)bs.GetBuffer(), bs.Len(), STREAM_READ); 1511 rOutliner.Read(aStream, String::CreateFromAscii(""), EE_FORMAT_RTF); 1512 OutlinerParaObject* pParaObject=rOutliner.CreateParaObject(); 1513 pStroke->NbcSetOutlinerParaObject(pParaObject); 1514 //delete pParaObject; 1515 rOutliner.Clear(); 1516 } 1517 if (txflTextFlow==2) { 1518 long nAngle = 90; 1519 double a = nAngle*100*nPi180; 1520 pStroke->Rotate(pStroke->GetCurrentBoundRect().Center(), nAngle*100, sin(a), cos(a) ); 1521 1522 } 1523 1524 } 1525 break; 1526 case 20: /* Line */ 1527 { 1528 ::basegfx::B2DPolygon aLine; 1529 aLine.append(aPointLeftTop); 1530 aLine.append(aPointRightBottom); 1531 1532 SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aLine)); 1533 pSdrObject = pStroke; 1534 //pStroke->SetSnapRect(aRect); 1535 1536 InsertShpObject(pStroke, this->nZOrder++); 1537 SfxItemSet aSet(pStroke->GetMergedItemSet()); 1538 if (!fLine) { 1539 aSet.Put(XLineStyleItem(XLINE_NONE)); 1540 } else { 1541 aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width 1542 } 1543 1544 pStroke->SetMergedItemSet(aSet); 1545 } 1546 break; 1547 case 75 : /* Picture */ 1548 if (bGrfValid) { 1549 ::basegfx::B2DRange aRange(aPointLeftTop); 1550 aRange.expand(aPointRightBottom); 1551 const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY())); 1552 1553 SdrRectObj* pStroke = new SdrGrafObj(aGrf); 1554 pSdrObject = pStroke; 1555 pStroke->SetSnapRect(aRect); 1556 1557 InsertShpObject(pStroke, this->nZOrder++); 1558 } 1559 } 1560 if( pSdrObject ) 1561 { 1562 pSdrObject->SetDescription(sDescription); 1563 pSdrObject->SetTitle(sName); 1564 } 1565 } 1566 1567 extern void sw3io_ConvertFromOldField( SwDoc& rDoc, sal_uInt16& rWhich, 1568 sal_uInt16& rSubType, sal_uLong &rFmt, 1569 sal_uInt16 nVersion ); 1570 1571 sal_uInt16 SwRTFParser::ReadRevTbl() 1572 { 1573 // rStr.Erase( 0 ); 1574 int nNumOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !! 1575 sal_uInt16 nAuthorTableIndex = 0; 1576 1577 while( nNumOpenBrakets && IsParserWorking() ) 1578 { 1579 switch( nToken = GetNextToken() ) 1580 { 1581 case '}': --nNumOpenBrakets; break; 1582 case '{': 1583 { 1584 if( RTF_IGNOREFLAG != GetNextToken() ) 1585 nToken = SkipToken( -1 ); 1586 else if( RTF_UNKNOWNCONTROL != GetNextToken() ) 1587 nToken = SkipToken( -2 ); 1588 else 1589 { 1590 ReadUnknownData(); 1591 nToken = GetNextToken(); 1592 if( '}' != nToken ) 1593 eState = SVPAR_ERROR; 1594 break; 1595 } 1596 ++nNumOpenBrakets; 1597 } 1598 break; 1599 1600 case RTF_TEXTTOKEN: 1601 aToken.EraseTrailingChars(';'); 1602 1603 sal_uInt16 nSWId = pDoc->InsertRedlineAuthor(aToken); 1604 // Store matchpair 1605 if( !pAuthorInfos ) 1606 pAuthorInfos = new sw::util::AuthorInfos; 1607 sw::util::AuthorInfo* pAutorInfo = new sw::util::AuthorInfo( nAuthorTableIndex, nSWId ); 1608 if( 0 == pAuthorInfos->Insert( pAutorInfo ) ) 1609 delete pAutorInfo; 1610 1611 aRevTbl.push_back(aToken); 1612 nAuthorTableIndex++; 1613 break; 1614 } 1615 } 1616 SkipToken( -1 ); 1617 return nAuthorTableIndex; 1618 } 1619 1620 void SwRTFParser::NextToken( int nToken ) 1621 { 1622 sal_uInt16 eDateFmt; 1623 1624 switch( nToken ) 1625 { 1626 case RTF_FOOTNOTE: 1627 { 1628 //We can only insert a footnote if we're not inside a footnote. e.g. 1629 //#i7713# 1630 1631 // in insert mode it's also possible to be inside of a footnote! 1632 bool bInsertIntoFootnote = false; 1633 if( !IsNewDoc() ) 1634 { 1635 SwStartNode* pSttNode = pPam->GetNode()->StartOfSectionNode(); 1636 while(pSttNode && pSttNode->IsSectionNode()) 1637 { 1638 pSttNode = pSttNode->StartOfSectionNode(); 1639 } 1640 if( SwFootnoteStartNode == pSttNode->GetStartNodeType() ) 1641 bInsertIntoFootnote = true; 1642 } 1643 if (!mbIsFootnote && !bInsertIntoFootnote) 1644 { 1645 ReadHeaderFooter( nToken ); 1646 SkipToken( -1 ); // Klammer wieder zurueck 1647 } 1648 } 1649 break; 1650 case RTF_SWG_PRTDATA: 1651 ReadPrtData(); 1652 break; 1653 case RTF_XE: 1654 ReadXEField(); 1655 break; 1656 case RTF_FIELD: 1657 ReadField(); 1658 break; 1659 case RTF_SHPRSLT: 1660 ReadShpRslt(); 1661 break; 1662 case RTF_DO: 1663 ReadDrawingObject(); 1664 break; 1665 case RTF_SHP: 1666 ReadShapeObject(); 1667 break; 1668 case RTF_SHPPICT: 1669 case RTF_PICT: 1670 ReadBitmapData(); 1671 break; 1672 #ifdef READ_OLE_OBJECT 1673 case RTF_OBJECT: 1674 ReadOLEData(); 1675 break; 1676 #endif 1677 case RTF_TROWD: ReadTable( nToken ); break; 1678 case RTF_PGDSCTBL: 1679 if( !IsNewDoc() ) 1680 SkipPageDescTbl(); 1681 else 1682 ReadPageDescTbl(); 1683 break; 1684 case RTF_LISTTABLE: ReadListTable(); break; 1685 case RTF_LISTOVERRIDETABLE: ReadListOverrideTable(); break; 1686 1687 case RTF_LISTTEXT: 1688 GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 )); 1689 SkipGroup(); 1690 break; 1691 1692 case RTF_PN: 1693 if( bNewNumList ) 1694 SkipGroup(); 1695 else 1696 { 1697 bStyleTabValid = sal_True; 1698 if (SwNumRule* pRule = ReadNumSecLevel( nToken )) 1699 { 1700 GetAttrSet().Put( SwNumRuleItem( pRule->GetName() )); 1701 1702 if( SFX_ITEM_SET != GetAttrSet().GetItemState( FN_PARAM_NUM_LEVEL, sal_False )) 1703 GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 )); 1704 } 1705 } 1706 break; 1707 1708 1709 case RTF_BKMKSTART: 1710 if(RTF_TEXTTOKEN == GetNextToken()) 1711 mpBookmarkStart = new BookmarkPosition(*pPam); 1712 else 1713 SkipToken(-1); 1714 1715 SkipGroup(); 1716 break; 1717 1718 case RTF_BKMKEND: 1719 if(RTF_TEXTTOKEN == GetNextToken()) 1720 { 1721 const String& sBookmark = aToken; 1722 KeyCode aEmptyKeyCode; 1723 if (mpBookmarkStart) 1724 { 1725 BookmarkPosition aBookmarkEnd(*pPam); 1726 SwPaM aBookmarkRegion( mpBookmarkStart->maMkNode, mpBookmarkStart->mnMkCntnt, 1727 aBookmarkEnd.maMkNode, aBookmarkEnd.mnMkCntnt); 1728 if (*mpBookmarkStart == aBookmarkEnd) 1729 aBookmarkRegion.DeleteMark(); 1730 pDoc->getIDocumentMarkAccess()->makeMark(aBookmarkRegion, sBookmark, IDocumentMarkAccess::BOOKMARK); 1731 } 1732 delete mpBookmarkStart, mpBookmarkStart = 0; 1733 } 1734 else 1735 SkipToken(-1); 1736 1737 SkipGroup(); 1738 break; 1739 1740 1741 case RTF_PNSECLVL:{ 1742 if( bNewNumList) 1743 SkipGroup(); 1744 else 1745 ReadNumSecLevel( nToken ); 1746 break; 1747 } 1748 1749 case RTF_PNTEXT: 1750 case RTF_NONSHPPICT: 1751 SkipGroup(); 1752 break; 1753 1754 case RTF_DEFFORMAT: 1755 case RTF_DEFTAB: 1756 case RTF_DEFLANG: 1757 // sind zwar Dok-Controls, werden aber manchmal auch vor der 1758 // Font/Style/Color-Tabelle gesetzt! 1759 SvxRTFParser::NextToken( nToken ); 1760 break; 1761 1762 case RTF_PAGE: 1763 if (pTableNode==NULL) { //#117410#: A \page command within a table is ignored by Word. 1764 if (lcl_UsedPara(*pPam)) 1765 InsertPara(); 1766 CheckInsNewTblLine(); 1767 pDoc->InsertPoolItem(*pPam, 1768 SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0); 1769 } 1770 break; 1771 1772 case RTF_SECT: 1773 ReadSectControls( nToken ); 1774 break; 1775 case RTF_CELL: 1776 // --> OD 2008-12-22 #i83368# 1777 mbReadCellWhileReadSwFly = bReadSwFly; 1778 // <-- 1779 if (CantUseTables()) 1780 InsertPara(); 1781 else 1782 { 1783 // Tabelle nicht mehr vorhanden ? 1784 if (USHRT_MAX != nInsTblRow && !pTableNode) 1785 NewTblLine(); // evt. Line copieren 1786 GotoNextBox(); 1787 } 1788 break; 1789 1790 case RTF_ROW: 1791 bTrowdRead=false; 1792 if (!CantUseTables()) 1793 { 1794 // aus der Line raus 1795 m_nCurrentBox = 0; 1796 pTableNode = 0; 1797 // noch in der Tabelle drin? 1798 SwNodeIndex& rIdx = pPam->GetPoint()->nNode; 1799 const SwTableNode* pTblNd = rIdx.GetNode().FindTableNode(); 1800 if( pTblNd ) 1801 { 1802 // search the end of this row 1803 const SwStartNode* pBoxStt = 1804 rIdx.GetNode().FindTableBoxStartNode(); 1805 const SwTableBox* pBox = pTblNd->GetTable().GetTblBox( 1806 pBoxStt->GetIndex() ); 1807 const SwTableLine* pLn = pBox->GetUpper(); 1808 pBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ]; 1809 rIdx = *pBox->GetSttNd()->EndOfSectionNode(); 1810 pPam->Move( fnMoveForward, fnGoNode ); 1811 } 1812 nInsTblRow = static_cast< sal_uInt16 >(GetOpenBrakets()); 1813 SetPardTokenRead( sal_False ); 1814 SwPaM aTmp(*pPam); 1815 aTmp.Move( fnMoveBackward, fnGoNode ); 1816 } 1817 ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() ); 1818 break; 1819 1820 case RTF_INTBL: 1821 if (!CantUseTables()) 1822 { 1823 if( !pTableNode ) // Tabelle nicht mehr vorhanden ? 1824 { 1825 if (RTF_TROWD != GetNextToken()) 1826 NewTblLine(); // evt. Line copieren 1827 SkipToken(-1); 1828 } 1829 else 1830 { 1831 // Crsr nicht mehr in der Tabelle ? 1832 if( !pPam->GetNode()->FindTableNode() ) 1833 { 1834 // dann wieder in die letzte Box setzen 1835 // (kann durch einlesen von Flys geschehen!) 1836 pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode(); 1837 pPam->Move( fnMoveBackward ); 1838 } 1839 } 1840 } 1841 break; 1842 1843 case RTF_REVTBL: 1844 ReadRevTbl(); 1845 break; 1846 1847 case RTF_REVISED: 1848 pRedlineInsert = new SwFltRedline(nsRedlineType_t::REDLINE_INSERT, 0, DateTime(Date( 0 ), Time( 0 ))); 1849 break; 1850 1851 case RTF_DELETED: 1852 pRedlineDelete = new SwFltRedline(nsRedlineType_t::REDLINE_DELETE, 0, DateTime(Date( 0 ), Time( 0 ))); 1853 break; 1854 1855 case RTF_REVAUTH: 1856 { 1857 sw::util::AuthorInfo aEntry( static_cast< sal_uInt16 >(nTokenValue) ); 1858 sal_uInt16 nPos; 1859 1860 if(pRedlineInsert) 1861 { 1862 if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos)) 1863 { 1864 if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos)) 1865 { 1866 pRedlineInsert->nAutorNo = pAuthor->nOurId; 1867 } 1868 } 1869 } 1870 } 1871 break; 1872 1873 case RTF_REVAUTHDEL: 1874 { 1875 sw::util::AuthorInfo aEntry( static_cast< short >(nTokenValue) ); 1876 sal_uInt16 nPos; 1877 1878 if(pRedlineDelete) 1879 { 1880 if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos)) 1881 { 1882 if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos)) 1883 { 1884 pRedlineDelete->nAutorNo = pAuthor->nOurId; 1885 } 1886 } 1887 } 1888 } 1889 break; 1890 1891 case RTF_REVDTTM: 1892 if (pRedlineInsert != NULL) 1893 pRedlineInsert->aStamp = sw::ms::DTTM2DateTime(nTokenValue); 1894 1895 break; 1896 1897 case RTF_REVDTTMDEL: 1898 pRedlineDelete->aStamp = sw::ms::DTTM2DateTime(nTokenValue); 1899 break; 1900 1901 1902 case RTF_FLY_INPARA: 1903 // \pard und plain ueberlesen ! 1904 if( '}' != GetNextToken() && '}' != GetNextToken() ) 1905 { 1906 // Zeichengebundener Fly in Fly 1907 ReadHeaderFooter( nToken ); 1908 SetPardTokenRead( sal_False ); 1909 } 1910 break; 1911 1912 case RTF_PGDSCNO: 1913 if( IsNewDoc() && bSwPageDesc && 1914 sal_uInt16(nTokenValue) < pDoc->GetPageDescCnt() ) 1915 { 1916 const SwPageDesc* pPgDsc = 1917 &const_cast<const SwDoc *>(pDoc) 1918 ->GetPageDesc( sal_uInt16(nTokenValue) ); 1919 CheckInsNewTblLine(); 1920 pDoc->InsertPoolItem(*pPam, SwFmtPageDesc( pPgDsc ), 0); 1921 } 1922 break; 1923 1924 case RTF_COLUM: 1925 pDoc->InsertPoolItem(*pPam, 1926 SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE, RES_BREAK ), 0); 1927 break; 1928 1929 case RTF_DXFRTEXT: // werden nur im Zusammenhang mit Flys ausgewertet 1930 case RTF_DFRMTXTX: 1931 case RTF_DFRMTXTY: 1932 break; 1933 1934 case RTF_CHDATE: eDateFmt = DF_SHORT; goto SETCHDATEFIELD; 1935 case RTF_CHDATEA: eDateFmt = DF_SSYS; goto SETCHDATEFIELD; 1936 case RTF_CHDATEL: eDateFmt = DF_LSYS; goto SETCHDATEFIELD; 1937 SETCHDATEFIELD: 1938 { 1939 sal_uInt16 nSubType = DATEFLD, nWhich = RES_DATEFLD; 1940 sal_uLong nFormat = eDateFmt; 1941 sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 ); 1942 1943 SwDateTimeField aDateFld( (SwDateTimeFieldType*) 1944 pDoc->GetSysFldType( RES_DATETIMEFLD ), DATEFLD, nFormat); 1945 CheckInsNewTblLine(); 1946 pDoc->InsertPoolItem(*pPam, SwFmtFld( aDateFld ), 0); 1947 } 1948 break; 1949 1950 case RTF_CHTIME: 1951 { 1952 sal_uInt16 nSubType = TIMEFLD, nWhich = RES_TIMEFLD; 1953 sal_uLong nFormat = TF_SSMM_24; 1954 sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 ); 1955 SwDateTimeField aTimeFld( (SwDateTimeFieldType*) 1956 pDoc->GetSysFldType( RES_DATETIMEFLD ), TIMEFLD, nFormat); 1957 CheckInsNewTblLine(); 1958 pDoc->InsertPoolItem(*pPam, SwFmtFld( aTimeFld ), 0); 1959 } 1960 break; 1961 1962 case RTF_CHPGN: 1963 { 1964 SwPageNumberField aPageFld( (SwPageNumberFieldType*) 1965 pDoc->GetSysFldType( RES_PAGENUMBERFLD ), 1966 PG_RANDOM, SVX_NUM_ARABIC ); 1967 CheckInsNewTblLine(); 1968 pDoc->InsertPoolItem(*pPam, SwFmtFld(aPageFld), 0); 1969 } 1970 break; 1971 1972 case RTF_CHFTN: 1973 bFootnoteAutoNum = sal_True; 1974 break; 1975 1976 case RTF_NOFPAGES: 1977 if( IsNewDoc() && nTokenValue && -1 != nTokenValue ) 1978 ((SwDocStat&)pDoc->GetDocStat()).nPage = (sal_uInt16)nTokenValue; 1979 break; 1980 1981 case RTF_NOFWORDS: 1982 if( IsNewDoc() && nTokenValue && -1 != nTokenValue ) 1983 ((SwDocStat&)pDoc->GetDocStat()).nWord = (sal_uInt16)nTokenValue; 1984 break; 1985 case RTF_NOFCHARS: 1986 if( IsNewDoc() && nTokenValue && -1 != nTokenValue ) 1987 ((SwDocStat&)pDoc->GetDocStat()).nChar = (sal_uInt16)nTokenValue; 1988 break; 1989 case RTF_LYTPRTMET: 1990 if (IsNewDoc()) 1991 pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, false); 1992 break; 1993 case RTF_U: 1994 { 1995 CheckInsNewTblLine(); 1996 if( nTokenValue ) 1997 aToken = (sal_Unicode )nTokenValue; 1998 pDoc->InsertString( *pPam, aToken ); 1999 } 2000 break; 2001 2002 case RTF_USERPROPS: 2003 ReadUserProperties(); // #i28758 For now we don't support user properties 2004 break; 2005 2006 // RTF_SUBENTRYINDEX 2007 2008 default: 2009 switch( nToken & ~(0xff | RTF_SWGDEFS) ) 2010 { 2011 case RTF_DOCFMT: 2012 ReadDocControls( nToken ); 2013 break; 2014 case RTF_SECTFMT: 2015 ReadSectControls( nToken ); 2016 break; 2017 case RTF_APOCTL: 2018 if (nReadFlyDepth < 10) 2019 { 2020 nReadFlyDepth++; 2021 ReadFly( nToken ); 2022 nReadFlyDepth--; 2023 } 2024 break; 2025 2026 case RTF_BRDRDEF | RTF_TABLEDEF: 2027 case RTF_SHADINGDEF | RTF_TABLEDEF: 2028 case RTF_TABLEDEF: 2029 ReadTable( nToken ); 2030 break; 2031 2032 case RTF_INFO: 2033 ReadInfo(); 2034 break; 2035 2036 default: 2037 if( USHRT_MAX != nInsTblRow && 2038 (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() )) 2039 nInsTblRow = USHRT_MAX; 2040 2041 SvxRTFParser::NextToken( nToken ); 2042 break; 2043 } 2044 } 2045 if( USHRT_MAX != nInsTblRow && 2046 (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() )) 2047 nInsTblRow = USHRT_MAX; 2048 } 2049 2050 2051 2052 void SwRTFParser::InsertText() 2053 { 2054 bContainsPara = false; 2055 // dann fuege den String ein, ohne das Attribute am Ende 2056 // aufgespannt werden. 2057 CheckInsNewTblLine(); 2058 2059 if(pRedlineInsert) 2060 mpRedlineStack->open(*pPam->GetPoint(), *pRedlineInsert); 2061 if(pRedlineDelete) 2062 mpRedlineStack->open(*pPam->GetPoint(), *pRedlineDelete); 2063 2064 pDoc->InsertString( *pPam, aToken ); 2065 2066 if(pRedlineDelete) 2067 { 2068 mpRedlineStack->close(*pPam->GetPoint(), pRedlineDelete->eType); 2069 } 2070 2071 if(pRedlineInsert) 2072 { 2073 mpRedlineStack->close(*pPam->GetPoint(), pRedlineInsert->eType); 2074 } 2075 2076 2077 } 2078 2079 2080 void SwRTFParser::InsertPara() 2081 { 2082 bContainsPara = true; 2083 CheckInsNewTblLine(); 2084 pDoc->AppendTxtNode(*pPam->GetPoint()); 2085 2086 // setze das default Style 2087 if( !bStyleTabValid ) 2088 MakeStyleTab(); 2089 2090 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 ); 2091 if( !pColl ) 2092 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); 2093 pDoc->SetTxtFmtColl( *pPam, pColl ); 2094 2095 ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() ); 2096 } 2097 2098 2099 2100 void SwRTFParser::MovePos( int bForward ) 2101 { 2102 if( bForward ) 2103 pPam->Move( fnMoveForward ); 2104 else 2105 pPam->Move( fnMoveBackward ); 2106 } 2107 2108 int SwRTFParser::IsEndPara( SvxNodeIdx* pNd, xub_StrLen nCnt ) const 2109 { 2110 SwCntntNode *pNode = pDoc->GetNodes()[pNd->GetIdx()]->GetCntntNode(); 2111 return pNode && pNode->Len() == nCnt; 2112 } 2113 2114 bool SwRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &rSet) 2115 const 2116 { 2117 /* 2118 #i21961# 2119 Seeing as CHARFMT sets all the properties of the charfmt itself, its not 2120 good enough to just see it as a single property from the point of 2121 compressing property sets. If bold and charfmt are in a child, and bold is 2122 in the parent, removing bold from the child will not result in the same 2123 thing, if the charfmt removes bold itself for example 2124 */ 2125 bool bRet = false; 2126 if (rSet.GetAttrSet().Count()) 2127 { 2128 2129 if (SFX_ITEM_SET == 2130 rSet.GetAttrSet().GetItemState(RES_TXTATR_CHARFMT, sal_False)) 2131 { 2132 bRet = true; 2133 } 2134 } 2135 return bRet; 2136 } 2137 2138 void SwRTFParser::SetEndPrevPara( SvxNodeIdx*& rpNodePos, xub_StrLen& rCntPos ) 2139 { 2140 SwNodeIndex aIdx( pPam->GetPoint()->nNode ); 2141 SwCntntNode* pNode = pDoc->GetNodes().GoPrevious( &aIdx ); 2142 if( !pNode ) 2143 { 2144 ASSERT( sal_False, "keinen vorherigen ContentNode gefunden" ); 2145 } 2146 2147 rpNodePos = new SwNodeIdx( aIdx ); 2148 rCntPos = pNode->Len(); 2149 } 2150 2151 void SwRTFParser::SetAttrInDoc( SvxRTFItemStackType &rSet ) 2152 { 2153 sal_uLong nSNd = rSet.GetSttNodeIdx(), nENd = rSet.GetEndNodeIdx(); 2154 xub_StrLen nSCnt = rSet.GetSttCnt(), nECnt = rSet.GetEndCnt(); 2155 2156 SwPaM aPam( *pPam->GetPoint() ); 2157 2158 #ifdef DBG_UTIL 2159 ASSERT( nSNd <= nENd, "Start groesser als Ende" ); 2160 SwNode* pDebugNd = pDoc->GetNodes()[ nSNd ]; 2161 ASSERT( pDebugNd->IsCntntNode(), "Start kein ContentNode" ); 2162 pDebugNd = pDoc->GetNodes()[ nENd ]; 2163 ASSERT( pDebugNd->IsCntntNode(), "Ende kein ContentNode" ); 2164 #endif 2165 2166 SwCntntNode* pCNd = pDoc->GetNodes()[ nSNd ]->GetCntntNode(); 2167 aPam.GetPoint()->nNode = nSNd; 2168 aPam.GetPoint()->nContent.Assign( pCNd, nSCnt ); 2169 aPam.SetMark(); 2170 if( nENd == nSNd ) 2171 aPam.GetPoint()->nContent = nECnt; 2172 else 2173 { 2174 aPam.GetPoint()->nNode = nENd; 2175 pCNd = aPam.GetCntntNode(); 2176 aPam.GetPoint()->nContent.Assign( pCNd, nECnt ); 2177 } 2178 2179 // setze ueber den Bereich das entsprechende Style 2180 if( rSet.StyleNo() ) 2181 { 2182 // setze jetzt das Style 2183 if( !bStyleTabValid ) 2184 MakeStyleTab(); 2185 SwTxtFmtColl* pColl = aTxtCollTbl.Get( rSet.StyleNo() ); 2186 if( pColl ) 2187 pDoc->SetTxtFmtColl( aPam, pColl, false ); 2188 } 2189 2190 const SfxPoolItem* pItem; 2191 const SfxPoolItem* pCharFmt; 2192 if (rSet.GetAttrSet().Count() ) 2193 { 2194 2195 // falls eine Zeichenvorlage im Set steht, deren Attribute 2196 // aus dem Set loeschen. Sonst sind diese doppelt, was man ja 2197 // nicht will. 2198 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( 2199 RES_TXTATR_CHARFMT, sal_False, &pCharFmt ) && 2200 ((SwFmtCharFmt*)pCharFmt)->GetCharFmt() ) 2201 { 2202 const String& rName = ((SwFmtCharFmt*)pCharFmt)->GetCharFmt()->GetName(); 2203 SvxRTFStyleType* pStyle = GetStyleTbl().First(); 2204 do { 2205 if( pStyle->bIsCharFmt && pStyle->sName == rName ) 2206 { 2207 // alle Attribute, die schon vom Style definiert sind, aus dem 2208 // akt. AttrSet entfernen 2209 SfxItemSet &rAttrSet = rSet.GetAttrSet(), 2210 &rStyleSet = pStyle->aAttrSet; 2211 SfxItemIter aIter( rAttrSet ); 2212 sal_uInt16 nWhich = aIter.GetCurItem()->Which(); 2213 while( sal_True ) 2214 { 2215 const SfxPoolItem* pI; 2216 if( SFX_ITEM_SET == rStyleSet.GetItemState( 2217 nWhich, sal_False, &pI ) && *pI == *aIter.GetCurItem()) 2218 rAttrSet.ClearItem( nWhich ); // loeschen 2219 2220 if( aIter.IsAtEnd() ) 2221 break; 2222 nWhich = aIter.NextItem()->Which(); 2223 } 2224 break; 2225 } 2226 } while( 0 != (pStyle = GetStyleTbl().Next()) ); 2227 2228 pDoc->InsertPoolItem(aPam, *pCharFmt, 0); 2229 rSet.GetAttrSet().ClearItem(RES_TXTATR_CHARFMT); //test hack 2230 } 2231 if (rSet.GetAttrSet().Count()) 2232 { 2233 // dann setze ueber diesen Bereich die Attrbiute 2234 SetSwgValues(rSet.GetAttrSet()); 2235 pDoc->InsertItemSet(aPam, rSet.GetAttrSet(), 2236 nsSetAttrMode::SETATTR_DONTCHGNUMRULE); 2237 } 2238 } 2239 2240 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( 2241 FN_PARAM_NUM_LEVEL, sal_False, &pItem )) 2242 { 2243 // dann ueber den Bereich an den Nodes das NodeNum setzen 2244 for( sal_uLong n = nSNd; n <= nENd; ++n ) 2245 { 2246 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode(); 2247 if( pTxtNd ) 2248 { 2249 pTxtNd->SetAttrListLevel((sal_uInt8) ((SfxUInt16Item*)pItem)->GetValue()); 2250 // Update vom LR-Space abschalten? 2251 } 2252 } 2253 } 2254 2255 if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( 2256 RES_PARATR_NUMRULE, sal_False, &pItem )) 2257 { 2258 const SwNumRule* pRule = pDoc->FindNumRulePtr( 2259 ((SwNumRuleItem*)pItem)->GetValue() ); 2260 if( pRule && ( pRule->IsContinusNum() || !bNewNumList )) 2261 { 2262 // diese Rule hat keinen Level, also muss die Einrueckung 2263 // erhalten bleiben! 2264 // dann ueber den Bereich an den Nodes das Flag zuruecksetzen 2265 for( sal_uLong n = nSNd; n <= nENd; ++n ) 2266 { 2267 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode(); 2268 if( pTxtNd ) 2269 { 2270 // Update vom LR-Space abschalten 2271 pTxtNd->SetNumLSpace( sal_False ); 2272 } 2273 } 2274 } 2275 } 2276 2277 bool bNoNum = true; 2278 if ( 2279 (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(RES_PARATR_NUMRULE)) 2280 || (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(FN_PARAM_NUM_LEVEL)) 2281 ) 2282 { 2283 bNoNum = false; 2284 } 2285 2286 if (bNoNum) 2287 { 2288 for( sal_uLong n = nSNd; n <= nENd; ++n ) 2289 { 2290 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode(); 2291 if( pTxtNd ) 2292 { 2293 pTxtNd->SetAttr( *GetDfltAttr(RES_PARATR_NUMRULE) ); 2294 // reset all list attributes 2295 pTxtNd->ResetAttr( RES_PARATR_LIST_LEVEL ); 2296 pTxtNd->ResetAttr( RES_PARATR_LIST_ISRESTART ); 2297 pTxtNd->ResetAttr( RES_PARATR_LIST_RESTARTVALUE ); 2298 pTxtNd->ResetAttr( RES_PARATR_LIST_ISCOUNTED ); 2299 pTxtNd->ResetAttr( RES_PARATR_LIST_ID ); 2300 } 2301 } 2302 } 2303 } 2304 2305 DocPageInformation::DocPageInformation() 2306 : maBox( RES_BOX ), 2307 mnPaperw(12240), mnPaperh(15840), mnMargl(1800), mnMargr(1800), 2308 mnMargt(1440), mnMargb(1440), mnGutter(0), mnPgnStart(1), mbFacingp(false), 2309 mbLandscape(false), mbRTLdoc(false) 2310 { 2311 } 2312 2313 SectPageInformation::SectPageInformation(const DocPageInformation &rDoc) 2314 : maBox(rDoc.maBox), mpTitlePageHdFt(0), mpPageHdFt(0), 2315 mnPgwsxn(rDoc.mnPaperw), mnPghsxn(rDoc.mnPaperh), mnMarglsxn(rDoc.mnMargl), 2316 mnMargrsxn(rDoc.mnMargr), mnMargtsxn(rDoc.mnMargt), 2317 mnMargbsxn(rDoc.mnMargb), mnGutterxsn(rDoc.mnGutter), mnHeadery(720), 2318 mnFootery(720), mnPgnStarts(rDoc.mnPgnStart), mnCols(1), mnColsx(720), 2319 mnStextflow(rDoc.mbRTLdoc ? 3 : 0), mnBkc(2), mbLndscpsxn(rDoc.mbLandscape), 2320 mbTitlepg(false), mbFacpgsxn(rDoc.mbFacingp), mbRTLsection(rDoc.mbRTLdoc), 2321 mbPgnrestart(false), mbTitlePageHdFtUsed(false), mbPageHdFtUsed(false) 2322 { 2323 }; 2324 2325 SectPageInformation::SectPageInformation(const SectPageInformation &rSect) 2326 : maColumns(rSect.maColumns), maBox(rSect.maBox), 2327 maNumType(rSect.maNumType), mpTitlePageHdFt(rSect.mpTitlePageHdFt), 2328 mpPageHdFt(rSect.mpPageHdFt), mnPgwsxn(rSect.mnPgwsxn), 2329 mnPghsxn(rSect.mnPghsxn), mnMarglsxn(rSect.mnMarglsxn), 2330 mnMargrsxn(rSect.mnMargrsxn), mnMargtsxn(rSect.mnMargtsxn), 2331 mnMargbsxn(rSect.mnMargbsxn), mnGutterxsn(rSect.mnGutterxsn), 2332 mnHeadery(rSect.mnHeadery), mnFootery(rSect.mnFootery), 2333 mnPgnStarts(rSect.mnPgnStarts), mnCols(rSect.mnCols), 2334 mnColsx(rSect.mnColsx), mnStextflow(rSect.mnStextflow), mnBkc(rSect.mnBkc), 2335 mbLndscpsxn(rSect.mbLndscpsxn), mbTitlepg(rSect.mbTitlepg), 2336 mbFacpgsxn(rSect.mbFacpgsxn), mbRTLsection(rSect.mbRTLsection), 2337 mbPgnrestart(rSect.mbPgnrestart), 2338 mbTitlePageHdFtUsed(rSect.mbTitlePageHdFtUsed), 2339 mbPageHdFtUsed(rSect.mbPageHdFtUsed) 2340 { 2341 }; 2342 2343 rtfSection::rtfSection(const SwPosition &rPos, 2344 const SectPageInformation &rPageInfo) 2345 : maStart(rPos.nNode), maPageInfo(rPageInfo), mpSection(0), mpTitlePage(0), 2346 mpPage(0) 2347 { 2348 } 2349 2350 void rtfSections::push_back(const rtfSection &rSect) 2351 { 2352 if (!maSegments.empty() && (maSegments.back().maStart == rSect.maStart)) 2353 maSegments.pop_back(); 2354 maSegments.push_back(rSect); 2355 } 2356 2357 // lese alle Dokument-Controls ein 2358 void SwRTFParser::SetPageInformationAsDefault(const DocPageInformation &rInfo) 2359 { 2360 //If we are at the beginning of the document then start the document with 2361 //a segment with these properties. See #i14982# for this requirement 2362 rtfSection aSect(*pPam->GetPoint(), SectPageInformation(rInfo)); 2363 if (maSegments.empty() || (maSegments.back().maStart == aSect.maStart)) 2364 maSegments.push_back(aSect); 2365 2366 if (!bSwPageDesc && IsNewDoc()) 2367 { 2368 SwFmtFrmSize aFrmSize(ATT_FIX_SIZE, rInfo.mnPaperw, rInfo.mnPaperh); 2369 2370 SvxLRSpaceItem aLR( static_cast< sal_uInt16 >(rInfo.mnMargl), static_cast< sal_uInt16 >(rInfo.mnMargr), 0, 0, RES_LR_SPACE ); 2371 SvxULSpaceItem aUL( static_cast< sal_uInt16 >(rInfo.mnMargt), static_cast< sal_uInt16 >(rInfo.mnMargb), RES_UL_SPACE ); 2372 2373 UseOnPage eUseOn; 2374 if (rInfo.mbFacingp) 2375 eUseOn = UseOnPage(nsUseOnPage::PD_MIRROR | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE); 2376 else 2377 eUseOn = UseOnPage(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE); 2378 2379 sal_uInt16 nPgStart = static_cast< sal_uInt16 >(rInfo.mnPgnStart); 2380 2381 SvxFrameDirectionItem aFrmDir(rInfo.mbRTLdoc ? 2382 FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR); 2383 2384 // direkt an der Standartseite drehen 2385 SwPageDesc& rPg = pDoc->_GetPageDesc( 0 ); 2386 rPg.WriteUseOn( eUseOn ); 2387 2388 if (rInfo.mbLandscape) 2389 rPg.SetLandscape(true); 2390 2391 SwFrmFmt &rFmt1 = rPg.GetMaster(), &rFmt2 = rPg.GetLeft(); 2392 2393 rFmt1.SetFmtAttr( aFrmSize ); rFmt2.SetFmtAttr( aFrmSize ); 2394 rFmt1.SetFmtAttr( aLR ); rFmt2.SetFmtAttr( aLR ); 2395 rFmt1.SetFmtAttr( aUL ); rFmt2.SetFmtAttr( aUL ); 2396 rFmt1.SetFmtAttr( aFrmDir ); rFmt2.SetFmtAttr( aFrmDir ); 2397 2398 // StartNummer der Seiten setzen 2399 if (nPgStart != 1) 2400 { 2401 SwFmtPageDesc aPgDsc( &rPg ); 2402 aPgDsc.SetNumOffset( nPgStart ); 2403 pDoc->InsertPoolItem( *pPam, aPgDsc, 0 ); 2404 } 2405 } 2406 } 2407 2408 void SwRTFParser::SetBorderLine(SvxBoxItem& rBox, sal_uInt16 nLine) 2409 { 2410 int bWeiter = true; 2411 short nLineThickness = 1; 2412 short nPageDistance = 0; 2413 sal_uInt8 nCol = 0; 2414 short nIdx = 0; 2415 2416 int nToken = GetNextToken(); 2417 do { 2418 switch( nToken ) 2419 { 2420 case RTF_BRDRS: 2421 nIdx = 1; 2422 break; 2423 2424 case RTF_BRDRDB: 2425 nIdx = 3; 2426 break; 2427 2428 case RTF_BRDRTRIPLE: 2429 nIdx = 10; 2430 break; 2431 2432 case RTF_BRDRTNTHSG: 2433 nIdx = 11; 2434 break; 2435 2436 case RTF_BRDRTHTNSG: 2437 nIdx = 12; 2438 break; 2439 2440 case RTF_BRDRTNTHTNSG: 2441 nIdx = 13; 2442 break; 2443 2444 case RTF_BRDRTNTHMG: 2445 nIdx = 14; 2446 break; 2447 2448 case RTF_BRDRTHTNMG: 2449 nIdx = 15; 2450 break; 2451 2452 case RTF_BRDRTNTHTNMG: 2453 nIdx = 16; 2454 break; 2455 2456 case RTF_BRDRTNTHLG: 2457 nIdx = 17; 2458 break; 2459 2460 case RTF_BRDRTHTNLG: 2461 nIdx = 18; 2462 break; 2463 2464 case RTF_BRDRTNTHTNLG: 2465 nIdx = 19; 2466 break; 2467 2468 case RTF_BRDRWAVY: 2469 nIdx = 20; 2470 break; 2471 2472 case RTF_BRDRWAVYDB: 2473 nIdx = 21; 2474 break; 2475 2476 case RTF_BRDREMBOSS: 2477 nIdx = 24; 2478 break; 2479 2480 case RTF_BRDRENGRAVE: 2481 nIdx = 25; 2482 break; 2483 2484 case RTF_BRSP: 2485 nPageDistance = static_cast< short >(nTokenValue); 2486 break; 2487 2488 case RTF_BRDRDOT: // SO does not have dashed or dotted lines 2489 case RTF_BRDRDASH: 2490 case RTF_BRDRDASHSM: 2491 case RTF_BRDRDASHD: 2492 case RTF_BRDRDASHDD: 2493 case RTF_BRDRDASHDOTSTR: 2494 case RTF_BRDRSH: // shading not supported 2495 case RTF_BRDRCF: // colors not supported 2496 break; 2497 2498 case RTF_BRDRW: 2499 nLineThickness = static_cast< short >(nTokenValue); 2500 break; 2501 default: 2502 bWeiter = false; 2503 SkipToken(-1); 2504 break; 2505 } 2506 if (bWeiter) 2507 nToken = GetNextToken(); 2508 } while (bWeiter && IsParserWorking()); 2509 2510 GetLineIndex(rBox, nLineThickness, nPageDistance, nCol, nIdx, nLine, nLine, 0); 2511 } 2512 2513 // lese alle Dokument-Controls ein 2514 void SwRTFParser::ReadDocControls( int nToken ) 2515 { 2516 int bWeiter = true; 2517 2518 SwFtnInfo aFtnInfo; 2519 SwEndNoteInfo aEndInfo; 2520 bool bSetHyph = false; 2521 2522 sal_Bool bEndInfoChgd = sal_False, bFtnInfoChgd = sal_False; 2523 2524 do { 2525 sal_uInt16 nValue = sal_uInt16( nTokenValue ); 2526 switch( nToken ) 2527 { 2528 case RTF_RTLDOC: 2529 maPageDefaults.mbRTLdoc = true; 2530 break; 2531 case RTF_LTRDOC: 2532 maPageDefaults.mbRTLdoc = false; 2533 break; 2534 case RTF_LANDSCAPE: 2535 maPageDefaults.mbLandscape = true; 2536 break; 2537 case RTF_PAPERW: 2538 if( 0 < nTokenValue ) 2539 maPageDefaults.mnPaperw = nTokenValue; 2540 break; 2541 case RTF_PAPERH: 2542 if( 0 < nTokenValue ) 2543 maPageDefaults.mnPaperh = nTokenValue; 2544 break; 2545 case RTF_MARGL: 2546 if( 0 <= nTokenValue ) 2547 maPageDefaults.mnMargl = nTokenValue; 2548 break; 2549 case RTF_MARGR: 2550 if( 0 <= nTokenValue ) 2551 maPageDefaults.mnMargr = nTokenValue; 2552 break; 2553 case RTF_MARGT: 2554 if( 0 <= nTokenValue ) 2555 maPageDefaults.mnMargt = nTokenValue; 2556 break; 2557 case RTF_MARGB: 2558 if( 0 <= nTokenValue ) 2559 maPageDefaults.mnMargb = nTokenValue; 2560 break; 2561 case RTF_FACINGP: 2562 maPageDefaults.mbFacingp = true; 2563 break; 2564 case RTF_PGNSTART: 2565 maPageDefaults.mnPgnStart = nTokenValue; 2566 break; 2567 case RTF_ENDDOC: 2568 case RTF_ENDNOTES: 2569 aFtnInfo.ePos = FTNPOS_CHAPTER; bFtnInfoChgd = sal_True; 2570 break; 2571 case RTF_FTNTJ: 2572 case RTF_FTNBJ: 2573 aFtnInfo.ePos = FTNPOS_PAGE; bFtnInfoChgd = sal_True; 2574 break; 2575 2576 case RTF_AENDDOC: 2577 case RTF_AENDNOTES: 2578 case RTF_AFTNTJ: 2579 case RTF_AFTNBJ: 2580 case RTF_AFTNRESTART: 2581 case RTF_AFTNRSTCONT: 2582 break; // wir kenn nur am Doc Ende und Doc weite Num.! 2583 2584 case RTF_FTNSTART: 2585 if( nValue ) 2586 { 2587 aFtnInfo.nFtnOffset = nValue-1; 2588 bFtnInfoChgd = sal_True; 2589 } 2590 break; 2591 case RTF_AFTNSTART: 2592 if( nValue ) 2593 { 2594 aEndInfo.nFtnOffset = nValue-1; 2595 bEndInfoChgd = sal_True; 2596 } 2597 break; 2598 case RTF_FTNRSTPG: 2599 aFtnInfo.eNum = FTNNUM_PAGE; bFtnInfoChgd = sal_True; 2600 break; 2601 case RTF_FTNRESTART: 2602 aFtnInfo.eNum = FTNNUM_CHAPTER; bFtnInfoChgd = sal_True; 2603 break; 2604 case RTF_FTNRSTCONT: 2605 aFtnInfo.eNum = FTNNUM_DOC; bFtnInfoChgd = sal_True; 2606 break; 2607 2608 case RTF_FTNNAR: 2609 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bFtnInfoChgd = sal_True; break; 2610 case RTF_FTNNALC: 2611 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N); bFtnInfoChgd = sal_True; break; 2612 case RTF_FTNNAUC: 2613 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N); bFtnInfoChgd = sal_True; break; 2614 case RTF_FTNNRLC: 2615 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER); bFtnInfoChgd = sal_True; break; 2616 case RTF_FTNNRUC: 2617 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER); bFtnInfoChgd = sal_True; break; 2618 case RTF_FTNNCHI: 2619 aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL); bFtnInfoChgd = sal_True; break; 2620 2621 case RTF_AFTNNAR: 2622 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bEndInfoChgd = sal_True; break; 2623 case RTF_AFTNNALC: 2624 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N); 2625 bEndInfoChgd = sal_True; 2626 break; 2627 case RTF_AFTNNAUC: 2628 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N); 2629 bEndInfoChgd = sal_True; 2630 break; 2631 case RTF_AFTNNRLC: 2632 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER); 2633 bEndInfoChgd = sal_True; 2634 break; 2635 case RTF_AFTNNRUC: 2636 aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER); 2637 bEndInfoChgd = sal_True; 2638 break; 2639 case RTF_AFTNNCHI: 2640 aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL); 2641 bEndInfoChgd = sal_True; 2642 break; 2643 case RTF_HYPHAUTO: 2644 if (nTokenValue) 2645 bSetHyph = true; 2646 //FOO// 2647 break; 2648 case RTF_PGBRDRT: 2649 SetBorderLine(maPageDefaults.maBox, BOX_LINE_TOP); 2650 break; 2651 2652 case RTF_PGBRDRB: 2653 SetBorderLine(maPageDefaults.maBox, BOX_LINE_BOTTOM); 2654 break; 2655 2656 case RTF_PGBRDRL: 2657 SetBorderLine(maPageDefaults.maBox, BOX_LINE_LEFT); 2658 break; 2659 2660 case RTF_PGBRDRR: 2661 SetBorderLine(maPageDefaults.maBox, BOX_LINE_RIGHT); 2662 break; 2663 2664 case '{': 2665 { 2666 short nSkip = 0; 2667 if( RTF_IGNOREFLAG != GetNextToken() ) 2668 nSkip = -1; 2669 else if( RTF_DOCFMT != (( nToken = GetNextToken() ) 2670 & ~(0xff | RTF_SWGDEFS)) ) 2671 nSkip = -2; 2672 else 2673 { 2674 SkipGroup(); // erstmal komplett ueberlesen 2675 // ueberlese noch die schliessende Klammer 2676 GetNextToken(); 2677 } 2678 if( nSkip ) 2679 { 2680 SkipToken( nSkip ); // Ignore wieder zurueck 2681 bWeiter = sal_False; 2682 } 2683 } 2684 break; 2685 2686 default: 2687 if( RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS)) || 2688 RTF_UNKNOWNCONTROL == nToken ) 2689 SvxRTFParser::NextToken( nToken ); 2690 else 2691 bWeiter = sal_False; 2692 break; 2693 } 2694 if( bWeiter ) 2695 nToken = GetNextToken(); 2696 } while( bWeiter && IsParserWorking() ); 2697 2698 if (IsNewDoc()) 2699 { 2700 if( bEndInfoChgd ) 2701 pDoc->SetEndNoteInfo( aEndInfo ); 2702 if( bFtnInfoChgd ) 2703 pDoc->SetFtnInfo( aFtnInfo ); 2704 } 2705 2706 if (!bSwPageDesc) 2707 { 2708 SetPageInformationAsDefault(maPageDefaults); 2709 2710 MakeStyleTab(); 2711 2712 SwTxtFmtColl* pColl = aTxtCollTbl.Get(0); 2713 if (!pColl) 2714 { 2715 pColl = pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ); 2716 } 2717 2718 ASSERT(pColl, "impossible to have no standard style"); 2719 2720 if (pColl) 2721 { 2722 if ( 2723 IsNewDoc() && bSetHyph && 2724 SFX_ITEM_SET != pColl->GetItemState(RES_PARATR_HYPHENZONE, 2725 false) 2726 ) 2727 { 2728 pColl->SetFmtAttr(SvxHyphenZoneItem(true, RES_PARATR_HYPHENZONE)); 2729 } 2730 2731 pDoc->SetTxtFmtColl( *pPam, pColl ); 2732 } 2733 } 2734 2735 SkipToken( -1 ); 2736 } 2737 2738 void SwRTFParser::MakeStyleTab() 2739 { 2740 // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections 2741 if( GetStyleTbl().Count() ) 2742 { 2743 sal_uInt16 nValidOutlineLevels = 0; 2744 if( !IsNewDoc() ) 2745 { 2746 // search all outlined collections 2747 //sal_uInt8 nLvl; 2748 const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls(); 2749 for( sal_uInt16 n = rColls.Count(); n; ) 2750 //if( MAXLEVEL > (nLvl = rColls[ --n ]->GetOutlineLevel() ))//#outline level,zhaojianwei 2751 // nValidOutlineLevels |= 1 << nLvl; 2752 if( rColls[ --n ]->IsAssignedToListLevelOfOutlineStyle()) 2753 nValidOutlineLevels |= 1 << rColls[ n ]->GetAssignedOutlineStyleLevel();//<-end,zhaojianwei 2754 } 2755 2756 SvxRTFStyleType* pStyle = GetStyleTbl().First(); 2757 do { 2758 sal_uInt16 nNo = sal_uInt16( GetStyleTbl().GetCurKey() ); 2759 if( pStyle->bIsCharFmt ) 2760 { 2761 if( !aCharFmtTbl.Get( nNo ) ) 2762 // existiert noch nicht, also anlegen 2763 MakeCharStyle( nNo, *pStyle ); 2764 } 2765 else if( !aTxtCollTbl.Get( nNo ) ) 2766 { 2767 // existiert noch nicht, also anlegen 2768 MakeStyle( nNo, *pStyle ); 2769 } 2770 2771 } while( 0 != (pStyle = GetStyleTbl().Next()) ); 2772 bStyleTabValid = sal_True; 2773 } 2774 } 2775 2776 sal_Bool lcl_SetFmtCol( SwFmt& rFmt, sal_uInt16 nCols, sal_uInt16 nColSpace, 2777 const SvUShorts& rColumns ) 2778 { 2779 sal_Bool bSet = sal_False; 2780 if( nCols && USHRT_MAX != nCols ) 2781 { 2782 SwFmtCol aCol; 2783 if( USHRT_MAX == nColSpace ) 2784 nColSpace = 720; 2785 2786 aCol.Init( nCols, nColSpace, USHRT_MAX ); 2787 if( nCols == ( rColumns.Count() / 2 ) ) 2788 { 2789 aCol._SetOrtho( sal_False ); 2790 sal_uInt16 nWishWidth = 0, nHalfPrev = 0; 2791 for (sal_uInt16 n = 0, i = 0; (n+1) < rColumns.Count(); n += 2, ++i) 2792 { 2793 SwColumn* pCol = aCol.GetColumns()[ i ]; 2794 pCol->SetLeft( nHalfPrev ); 2795 sal_uInt16 nSp = rColumns[ n+1 ]; 2796 nHalfPrev = nSp / 2; 2797 pCol->SetRight( nSp - nHalfPrev ); 2798 pCol->SetWishWidth( rColumns[ n ] + 2799 pCol->GetLeft() + pCol->GetRight() ); 2800 nWishWidth = nWishWidth + pCol->GetWishWidth(); 2801 } 2802 aCol.SetWishWidth( nWishWidth ); 2803 } 2804 rFmt.SetFmtAttr( aCol ); 2805 bSet = sal_True; 2806 } 2807 return bSet; 2808 } 2809 2810 void SwRTFParser::DoHairyWriterPageDesc(int nToken) 2811 { 2812 int bWeiter = sal_True; 2813 do { 2814 if( '{' == nToken ) 2815 { 2816 switch( nToken = GetNextToken() ) 2817 { 2818 case RTF_IGNOREFLAG: 2819 if( RTF_SECTFMT != (( nToken = GetNextToken() ) 2820 & ~(0xff | RTF_SWGDEFS)) ) 2821 { 2822 SkipToken( -2 ); // Ignore und Token wieder zurueck 2823 bWeiter = sal_False; 2824 break; 2825 } 2826 // kein break, Gruppe ueberspringen 2827 2828 case RTF_FOOTER: 2829 case RTF_HEADER: 2830 case RTF_FOOTERR: 2831 case RTF_HEADERR: 2832 case RTF_FOOTERL: 2833 case RTF_HEADERL: 2834 case RTF_FOOTERF: 2835 case RTF_HEADERF: 2836 SkipGroup(); // erstmal komplett ueberlesen 2837 // ueberlese noch die schliessende Klammer 2838 GetNextToken(); 2839 break; 2840 2841 default: 2842 SkipToken( -1 ); // Ignore wieder zurueck 2843 bWeiter = sal_False; 2844 break; 2845 } 2846 } 2847 else if( RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) || 2848 RTF_UNKNOWNCONTROL == nToken ) 2849 SvxRTFParser::NextToken( nToken ); 2850 else 2851 bWeiter = sal_False; 2852 if( bWeiter ) 2853 nToken = GetNextToken(); 2854 } while( bWeiter && IsParserWorking() ); 2855 SkipToken( -1 ); // letztes Token wieder zurueck 2856 return; 2857 } 2858 2859 void SwRTFParser::ReadSectControls( int nToken ) 2860 { 2861 //this is some hairy stuff to try and retain writer style page descriptors 2862 //in rtf, almost certainy a bad idea, but we've inherited it, so here it 2863 //stays 2864 if (bInPgDscTbl) 2865 { 2866 DoHairyWriterPageDesc(nToken); 2867 return; 2868 } 2869 2870 ASSERT(!maSegments.empty(), "suspicious to have a section with no " 2871 "page info, though probably legal"); 2872 if (maSegments.empty()) 2873 { 2874 maSegments.push_back(rtfSection(*pPam->GetPoint(), 2875 SectPageInformation(maPageDefaults))); 2876 } 2877 2878 SectPageInformation aNewSection(maSegments.back().maPageInfo); 2879 2880 bool bNewSection = false; 2881 bool bNewSectionHeader = false; 2882 const SwFmtHeader* _pKeepHeader = NULL; 2883 const SwFmtFooter* _pKeepFooter = NULL; 2884 int bWeiter = true; 2885 bool bKeepFooter = false; 2886 do { 2887 sal_uInt16 nValue = sal_uInt16( nTokenValue ); 2888 switch( nToken ) 2889 { 2890 case RTF_SECT: 2891 bNewSection = true; 2892 bForceNewTable = true; // #117882# 2893 break; 2894 case RTF_SECTD: { 2895 //Reset to page defaults 2896 SwPageDesc* oldPageDesc=aNewSection.mpPageHdFt; 2897 aNewSection = SectPageInformation(maPageDefaults); 2898 aNewSection.mpPageHdFt=oldPageDesc; 2899 _pKeepHeader = NULL; 2900 _pKeepFooter = NULL; 2901 } break; 2902 case RTF_PGWSXN: 2903 if (0 < nTokenValue) 2904 aNewSection.mnPgwsxn = nTokenValue; 2905 break; 2906 case RTF_PGHSXN: 2907 if (0 < nTokenValue) 2908 aNewSection.mnPghsxn = nTokenValue; 2909 break; 2910 case RTF_MARGLSXN: 2911 if (0 <= nTokenValue) 2912 aNewSection.mnMarglsxn = nTokenValue; 2913 break; 2914 case RTF_MARGRSXN: 2915 if (0 <= nTokenValue) 2916 aNewSection.mnMargrsxn = nTokenValue; 2917 break; 2918 case RTF_MARGTSXN: 2919 if (0 <= nTokenValue) 2920 aNewSection.mnMargtsxn = nTokenValue; 2921 break; 2922 case RTF_MARGBSXN: 2923 if (0 <= nTokenValue) 2924 aNewSection.mnMargbsxn = nTokenValue; 2925 break; 2926 case RTF_FACPGSXN: 2927 aNewSection.mbFacpgsxn = true; 2928 break; 2929 case RTF_HEADERY: 2930 aNewSection.mnHeadery = nTokenValue; 2931 break; 2932 case RTF_FOOTERY: 2933 aNewSection.mnFootery = nTokenValue; 2934 break; 2935 case RTF_LNDSCPSXN: 2936 aNewSection.mbLndscpsxn = true; 2937 break; 2938 case RTF_PGNSTARTS: 2939 aNewSection.mnPgnStarts = nTokenValue; 2940 break; 2941 case RTF_PGNDEC: 2942 aNewSection.maNumType.SetNumberingType(SVX_NUM_ARABIC); 2943 break; 2944 case RTF_PGNUCRM: 2945 aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_UPPER); 2946 break; 2947 case RTF_PGNLCRM: 2948 aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_LOWER); 2949 break; 2950 case RTF_PGNUCLTR: 2951 aNewSection.maNumType.SetNumberingType( 2952 SVX_NUM_CHARS_UPPER_LETTER_N); 2953 break; 2954 case RTF_PGNLCLTR: 2955 aNewSection.maNumType.SetNumberingType( 2956 SVX_NUM_CHARS_LOWER_LETTER_N); 2957 break; 2958 case RTF_SBKNONE: 2959 aNewSection.mnBkc = 0; 2960 break; 2961 case RTF_SBKCOL: 2962 aNewSection.mnBkc = 1; 2963 break; 2964 case RTF_PGBRDRT: 2965 SetBorderLine(aNewSection.maBox, BOX_LINE_TOP); 2966 break; 2967 2968 case RTF_PGBRDRB: 2969 SetBorderLine(aNewSection.maBox, BOX_LINE_BOTTOM); 2970 break; 2971 2972 case RTF_PGBRDRL: 2973 SetBorderLine(aNewSection.maBox, BOX_LINE_LEFT); 2974 break; 2975 2976 case RTF_PGBRDRR: 2977 SetBorderLine(aNewSection.maBox, BOX_LINE_RIGHT); 2978 break; 2979 2980 case RTF_PGBRDROPT: 2981 case RTF_ENDNHERE: 2982 case RTF_BINFSXN: 2983 case RTF_BINSXN: 2984 case RTF_SBKPAGE: 2985 case RTF_SBKEVEN: 2986 case RTF_SBKODD: 2987 case RTF_LINEBETCOL: 2988 case RTF_LINEMOD: 2989 case RTF_LINEX: 2990 case RTF_LINESTARTS: 2991 case RTF_LINERESTART: 2992 case RTF_LINEPAGE: 2993 case RTF_LINECONT: 2994 case RTF_GUTTERSXN: 2995 case RTF_PGNCONT: 2996 case RTF_PGNRESTART: 2997 case RTF_PGNX: 2998 case RTF_PGNY: 2999 case RTF_VERTALT: 3000 case RTF_VERTALB: 3001 case RTF_VERTALC: 3002 case RTF_VERTALJ: 3003 break; 3004 case RTF_TITLEPG: 3005 aNewSection.mbTitlepg = true; 3006 break; 3007 case RTF_HEADER: 3008 case RTF_HEADERL: 3009 case RTF_HEADERR: 3010 if (aNewSection.mpPageHdFt!=NULL) 3011 { 3012 _pKeepHeader = NULL; 3013 bKeepFooter = true; // #i82008 3014 _pKeepFooter = &aNewSection.mpPageHdFt->GetMaster().GetFooter(); 3015 } 3016 case RTF_FOOTER: 3017 case RTF_FOOTERL: 3018 case RTF_FOOTERR: 3019 if (aNewSection.mpPageHdFt!=NULL && !bKeepFooter ) 3020 { 3021 _pKeepFooter = NULL; 3022 _pKeepHeader = &aNewSection.mpPageHdFt->GetMaster().GetHeader(); 3023 } 3024 bKeepFooter = false; 3025 if (!bNewSectionHeader) { //see #117914# topic 2). If a header is redefined in a section 3026 bNewSectionHeader=true; // a new header must be created. 3027 aNewSection.mpPageHdFt=NULL; 3028 } 3029 if (!aNewSection.mpPageHdFt) 3030 { 3031 String aName(RTL_CONSTASCII_STRINGPARAM("rtfHdFt")); 3032 aName += String::CreateFromInt32(maSegments.size()); 3033 sal_uInt16 nPageNo = pDoc->MakePageDesc(aName); 3034 aNewSection.mpPageHdFt = &pDoc->_GetPageDesc(nPageNo); 3035 aNewSection.mbPageHdFtUsed = true; 3036 maSegments.maDummyPageNos.push_back(nPageNo); 3037 } 3038 ReadHeaderFooter(nToken, aNewSection.mpPageHdFt); 3039 if (_pKeepHeader) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepHeader); 3040 if (_pKeepFooter) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepFooter); 3041 break; 3042 case RTF_FOOTERF: 3043 case RTF_HEADERF: 3044 if (!aNewSection.mpTitlePageHdFt) 3045 { 3046 String aTitle(RTL_CONSTASCII_STRINGPARAM("rtfTitleHdFt")); 3047 aTitle += String::CreateFromInt32(maSegments.size()); 3048 sal_uInt16 nPageNo = pDoc->MakePageDesc(aTitle); 3049 aNewSection.mpTitlePageHdFt = &pDoc->_GetPageDesc(nPageNo); 3050 aNewSection.mbTitlePageHdFtUsed = true; 3051 maSegments.maDummyPageNos.push_back(nPageNo); 3052 } 3053 ReadHeaderFooter(nToken, aNewSection.mpTitlePageHdFt); 3054 break; 3055 case RTF_COLS: 3056 aNewSection.mnCols = nTokenValue; 3057 break; 3058 case RTF_COLSX: 3059 aNewSection.mnColsx = nTokenValue; 3060 break; 3061 case RTF_COLNO: 3062 { 3063 // next token must be either colw or colsr 3064 unsigned long nAktCol = nValue; 3065 long nWidth = 0, nSpace = 0; 3066 int nColToken = GetNextToken(); 3067 if (RTF_COLW == nColToken) 3068 { 3069 // next token could be colsr (but not required) 3070 nWidth = nTokenValue; 3071 if( RTF_COLSR == GetNextToken() ) 3072 nSpace = nTokenValue; 3073 else 3074 SkipToken( -1 ); // put back token 3075 } 3076 else if (RTF_COLSR == nColToken) 3077 { 3078 // next token must be colw (what sense should it make to have colsr only?!) 3079 nSpace = nTokenValue; 3080 if( RTF_COLW == GetNextToken() ) 3081 nWidth = nTokenValue; 3082 else 3083 // what should we do if an isolated colsr without colw is found? Doesn't make sense! 3084 SkipToken( -1 ); // put back token 3085 } 3086 else 3087 break; 3088 3089 if (--nAktCol == (aNewSection.maColumns.size() / 2)) 3090 { 3091 aNewSection.maColumns.push_back(nWidth); 3092 aNewSection.maColumns.push_back(nSpace); 3093 } 3094 } 3095 break; 3096 case RTF_STEXTFLOW: 3097 aNewSection.mnStextflow = nTokenValue; 3098 break; 3099 case RTF_RTLSECT: 3100 aNewSection.mbRTLsection = true; 3101 break; 3102 case RTF_LTRSECT: 3103 aNewSection.mbRTLsection = false; 3104 break; 3105 case '{': 3106 { 3107 short nSkip = 0; 3108 if( RTF_IGNOREFLAG != ( nToken = GetNextToken() )) 3109 nSkip = -1; 3110 else if( RTF_SECTFMT != (( nToken = GetNextToken() ) 3111 & ~(0xff | RTF_SWGDEFS)) && 3112 ( RTF_DOCFMT != ( nToken & ~(0xff | RTF_SWGDEFS))) ) 3113 nSkip = -2; 3114 else 3115 { 3116 // erstmal komplett ueberlesen 3117 SkipGroup(); 3118 // ueberlese noch die schliessende Klammer 3119 GetNextToken(); 3120 } 3121 if (nSkip) 3122 { 3123 bWeiter = ((-1 == nSkip) && 3124 ( 3125 RTF_FOOTER == nToken || RTF_HEADER == nToken || 3126 RTF_FOOTERR == nToken || RTF_HEADERR == nToken || 3127 RTF_FOOTERL == nToken || RTF_HEADERL == nToken || 3128 RTF_FOOTERF == nToken || RTF_HEADERF == nToken 3129 )); 3130 SkipToken (nSkip); // Ignore wieder zurueck 3131 } 3132 } 3133 break; 3134 case RTF_PAPERW: 3135 case RTF_PAPERH: 3136 case RTF_MARGL: 3137 case RTF_MARGR: 3138 case RTF_MARGT: 3139 case RTF_MARGB: 3140 case RTF_FACINGP: 3141 ASSERT(!this, "why are these tokens found in this section?"); 3142 ReadDocControls( nToken ); 3143 break; 3144 default: 3145 if (RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS))) 3146 ReadDocControls( nToken ); 3147 else if (RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) || 3148 RTF_UNKNOWNCONTROL == nToken) 3149 { 3150 SvxRTFParser::NextToken(nToken); 3151 } 3152 else 3153 bWeiter = false; 3154 break; 3155 } 3156 3157 if (bWeiter) 3158 nToken = GetNextToken(); 3159 } while (bWeiter && IsParserWorking()); 3160 3161 if (bNewSection || maSegments.empty()) 3162 { 3163 AttrGroupEnd(); //#106493# 3164 if(!bContainsPara && !bContainsTablePara) //#117881#: bContainsTablePara is set in rtftbl.cxx 3165 pDoc->AppendTxtNode(*pPam->GetPoint()); 3166 bContainsPara = false; 3167 bContainsTablePara = false; 3168 maSegments.push_back(rtfSection(*pPam->GetPoint(), aNewSection)); 3169 } 3170 else //modifying/replacing the current section 3171 { 3172 SwPaM aPamStart(maSegments.back().maStart); 3173 maSegments.pop_back(); 3174 maSegments.push_back(rtfSection(*aPamStart.GetPoint(), aNewSection)); 3175 } 3176 3177 SkipToken(-1); 3178 } 3179 3180 void SwRTFParser::EnterEnvironment() 3181 { 3182 } 3183 3184 3185 void SwRTFParser::LeaveEnvironment() 3186 { 3187 if(pRedlineDelete) 3188 { 3189 delete pRedlineDelete; 3190 pRedlineDelete = 0; 3191 } 3192 3193 if(pRedlineInsert) 3194 { 3195 delete pRedlineInsert; 3196 pRedlineInsert = 0; 3197 } 3198 } 3199 3200 void SwRTFParser::SkipPageDescTbl() 3201 { 3202 // M.M. #117907# I have to use this glorified SkipGroup because the 3203 // SvParser SkipGroup uses nNextCh which is not set correctly <groan> 3204 int nNumOpenBrakets = 1; 3205 3206 while( nNumOpenBrakets && IsParserWorking() ) 3207 { 3208 switch( GetNextToken() ) 3209 { 3210 case '}': 3211 { 3212 --nNumOpenBrakets; 3213 } 3214 break; 3215 3216 case '{': 3217 { 3218 nNumOpenBrakets++; 3219 } 3220 break; 3221 } 3222 } 3223 3224 SkipToken( -1 ); 3225 } 3226 3227 void SwRTFParser::ReadPageDescTbl() 3228 { 3229 // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections, damit 3230 // diese auch in den Headers/Footer benutzt werden koennen! 3231 MakeStyleTab(); 3232 // das default-Style schon gleich am ersten Node setzen 3233 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 ); 3234 if( !pColl ) 3235 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); 3236 pDoc->SetTxtFmtColl( *pPam, pColl ); 3237 3238 int nToken, bSaveChkStyleAttr = IsChkStyleAttr(); 3239 int nNumOpenBrakets = 1; // die erste wurde schon vorher erkannt !! 3240 3241 SetChkStyleAttr(sal_False); // Attribute nicht gegen die Styles checken 3242 3243 bInPgDscTbl = true; 3244 sal_uInt16 nPos = 0; 3245 SwPageDesc* pPg = 0; 3246 SwFrmFmt* pPgFmt = 0; 3247 3248 SvxULSpaceItem aUL( RES_UL_SPACE ), aHUL( RES_UL_SPACE ), aFUL( RES_UL_SPACE ); 3249 SvxLRSpaceItem aLR( RES_LR_SPACE ), aHLR( RES_LR_SPACE ), aFLR( RES_LR_SPACE ); 3250 Size a4 = SvxPaperInfo::GetPaperSize(PAPER_A4); 3251 SwFmtFrmSize aSz( ATT_FIX_SIZE, a4.Width(), a4.Height() ); // DIN A4 defaulten 3252 SwFmtFrmSize aFSz( ATT_MIN_SIZE ), aHSz( ATT_MIN_SIZE ); 3253 3254 SvxFrameDirectionItem aFrmDir(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR); 3255 3256 sal_uInt16 nCols = USHRT_MAX, nColSpace = USHRT_MAX, nAktCol = 0; 3257 SvUShorts aColumns; 3258 ::std::map< const SwPageDesc*, sal_uInt16 > aFollowMap; //store index of following page descriptors 3259 3260 while( nNumOpenBrakets && IsParserWorking() ) 3261 { 3262 switch( nToken = GetNextToken() ) 3263 { 3264 case '{': 3265 ++nNumOpenBrakets; 3266 break; 3267 case '}': 3268 if (1 == --nNumOpenBrakets) 3269 { 3270 ASSERT(pPgFmt && pPg, "Serious problem here"); 3271 if (pPgFmt && pPg) 3272 { 3273 // PageDesc ist fertig, setze am Doc 3274 pPgFmt->SetFmtAttr(aFrmDir); 3275 pPgFmt->SetFmtAttr(aLR); 3276 pPgFmt->SetFmtAttr(aUL); 3277 pPgFmt->SetFmtAttr(aSz); 3278 ::lcl_SetFmtCol(*pPgFmt, nCols, nColSpace, aColumns); 3279 if (pPgFmt->GetHeader().GetHeaderFmt()) 3280 { 3281 SwFrmFmt* pHFmt = 3282 (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt(); 3283 pHFmt->SetFmtAttr(aHUL); 3284 pHFmt->SetFmtAttr(aHLR); 3285 pHFmt->SetFmtAttr(aHSz); 3286 } 3287 if (pPgFmt->GetFooter().GetFooterFmt()) 3288 { 3289 SwFrmFmt* pFFmt = 3290 (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt(); 3291 pFFmt->SetFmtAttr(aHUL); 3292 pFFmt->SetFmtAttr(aHLR); 3293 pFFmt->SetFmtAttr(aHSz); 3294 } 3295 if( nPos < pDoc->GetPageDescCnt() ) 3296 pDoc->ChgPageDesc(nPos++, *pPg); 3297 } 3298 } 3299 break; 3300 case RTF_PGDSC: 3301 if (nPos) // kein && wg MAC 3302 { 3303 if (nPos != pDoc->MakePageDesc( 3304 String::CreateFromInt32(nTokenValue))) 3305 { 3306 ASSERT( sal_False, "PageDesc an falscher Position" ); 3307 } 3308 } 3309 pPg = &pDoc->_GetPageDesc(nPos); 3310 pPg->SetLandscape( sal_False ); 3311 pPgFmt = &pPg->GetMaster(); 3312 #ifndef CFRONT 3313 SETPAGEDESC_DEFAULTS: 3314 #endif 3315 aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() ); 3316 aLR.SetLeft( 0 ); aLR.SetRight( 0 ); 3317 aUL.SetLower( 0 ); aUL.SetUpper( 0 ); 3318 aHLR.SetLeft( 0 ); aHLR.SetRight( 0 ); 3319 aHUL.SetLower( 0 ); aHUL.SetUpper( 0 ); 3320 aFLR.SetLeft( 0 ); aFLR.SetRight( 0 ); 3321 aFUL.SetLower( 0 ); aFUL.SetUpper( 0 ); 3322 nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0; 3323 aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 ); 3324 aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 ); 3325 break; 3326 3327 case RTF_PGDSCUSE: 3328 pPg->WriteUseOn( (UseOnPage)nTokenValue ); 3329 break; 3330 3331 case RTF_PGDSCNXT: 3332 // store index of follow in map; will be fixed up later 3333 if( nTokenValue ) 3334 aFollowMap.insert( ::std::pair<const SwPageDesc*, sal_uInt16>( pPg, nTokenValue )); 3335 else 3336 pPg->SetFollow( & const_cast<const SwDoc *>(pDoc) 3337 ->GetPageDesc( 0 ) ); 3338 break; 3339 3340 case RTF_FORMULA: /* Zeichen "\|" !!! */ 3341 pPgFmt->SetFmtAttr( aLR ); 3342 pPgFmt->SetFmtAttr( aUL ); 3343 pPgFmt->SetFmtAttr( aSz ); 3344 ::lcl_SetFmtCol( *pPgFmt, nCols, nColSpace, aColumns ); 3345 if( pPgFmt->GetHeader().GetHeaderFmt() ) 3346 { 3347 SwFrmFmt* pHFmt = (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt(); 3348 pHFmt->SetFmtAttr( aHUL ); 3349 pHFmt->SetFmtAttr( aHLR ); 3350 pHFmt->SetFmtAttr( aHSz ); 3351 } 3352 if( pPgFmt->GetFooter().GetFooterFmt() ) 3353 { 3354 SwFrmFmt* pFFmt = (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt(); 3355 pFFmt->SetFmtAttr( aHUL ); 3356 pFFmt->SetFmtAttr( aHLR ); 3357 pFFmt->SetFmtAttr( aHSz ); 3358 } 3359 3360 pPgFmt = &pPg->GetLeft(); 3361 #ifndef CFRONT 3362 goto SETPAGEDESC_DEFAULTS; 3363 #else 3364 aLR.SetLeft( 0 ); aLR.SetRight( 0 ); 3365 aUL.SetLower( 0 ); aUL.SetUpper( 0 ); 3366 aHLR.SetLeft( 0 ); aHLR.SetRight( 0 ); 3367 aHUL.SetLower( 0 ); aHUL.SetUpper( 0 ); 3368 aFLR.SetLeft( 0 ); aFLR.SetRight( 0 ); 3369 aFUL.SetLower( 0 ); aFUL.SetUpper( 0 ); 3370 aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() ); // DIN A4 default 3371 nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0; 3372 aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 ); 3373 aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 ); 3374 break; 3375 #endif 3376 3377 case RTF_RTLSECT: 3378 aFrmDir.SetValue(FRMDIR_HORI_RIGHT_TOP); 3379 break; 3380 3381 case RTF_LTRSECT: 3382 aFrmDir.SetValue(FRMDIR_HORI_LEFT_TOP); 3383 break; 3384 3385 // alt: LI/RI/SA/SB, neu: MARG?SXN 3386 case RTF_MARGLSXN: 3387 case RTF_LI: aLR.SetLeft( (sal_uInt16)nTokenValue ); break; 3388 case RTF_MARGRSXN: 3389 case RTF_RI: aLR.SetRight( (sal_uInt16)nTokenValue ); break; 3390 case RTF_MARGTSXN: 3391 case RTF_SA: aUL.SetUpper( (sal_uInt16)nTokenValue ); break; 3392 case RTF_MARGBSXN: 3393 case RTF_SB: aUL.SetLower( (sal_uInt16)nTokenValue ); break; 3394 case RTF_PGWSXN: aSz.SetWidth( nTokenValue ); break; 3395 case RTF_PGHSXN: aSz.SetHeight( nTokenValue ); break; 3396 3397 case RTF_HEADERY: aHUL.SetUpper( (sal_uInt16)nTokenValue ); break; 3398 case RTF_HEADER_YB: aHUL.SetLower( (sal_uInt16)nTokenValue ); break; 3399 case RTF_HEADER_XL: aHLR.SetLeft( (sal_uInt16)nTokenValue ); break; 3400 case RTF_HEADER_XR: aHLR.SetRight( (sal_uInt16)nTokenValue ); break; 3401 case RTF_FOOTERY: aFUL.SetLower( (sal_uInt16)nTokenValue ); break; 3402 case RTF_FOOTER_YT: aFUL.SetUpper( (sal_uInt16)nTokenValue ); break; 3403 case RTF_FOOTER_XL: aFLR.SetLeft( (sal_uInt16)nTokenValue ); break; 3404 case RTF_FOOTER_XR: aFLR.SetRight( (sal_uInt16)nTokenValue ); break; 3405 3406 case RTF_HEADER_YH: 3407 if( 0 > nTokenValue ) 3408 { 3409 aHSz.SetHeightSizeType( ATT_FIX_SIZE ); 3410 nTokenValue = -nTokenValue; 3411 } 3412 aHSz.SetHeight( (sal_uInt16)nTokenValue ); 3413 break; 3414 3415 case RTF_FOOTER_YH: 3416 if( 0 > nTokenValue ) 3417 { 3418 aFSz.SetHeightSizeType( ATT_FIX_SIZE ); 3419 nTokenValue = -nTokenValue; 3420 } 3421 aFSz.SetHeight( (sal_uInt16)nTokenValue ); 3422 break; 3423 3424 3425 case RTF_LNDSCPSXN: pPg->SetLandscape( sal_True ); break; 3426 3427 case RTF_COLS: nCols = (sal_uInt16)nTokenValue; break; 3428 case RTF_COLSX: nColSpace = (sal_uInt16)nTokenValue; break; 3429 3430 case RTF_COLNO: 3431 nAktCol = (sal_uInt16)nTokenValue; 3432 if( RTF_COLW == GetNextToken() ) 3433 { 3434 sal_uInt16 nWidth = sal_uInt16( nTokenValue ), nSpace = 0; 3435 if( RTF_COLSR == GetNextToken() ) 3436 nSpace = sal_uInt16( nTokenValue ); 3437 else 3438 SkipToken( -1 ); // wieder zurueck 3439 3440 if( --nAktCol == ( aColumns.Count() / 2 ) ) 3441 { 3442 aColumns.Insert( nWidth, aColumns.Count() ); 3443 aColumns.Insert( nSpace, aColumns.Count() ); 3444 } 3445 } 3446 break; 3447 3448 case RTF_PAGEBB: 3449 { 3450 pPgFmt->SetFmtAttr( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ) ); 3451 } 3452 break; 3453 3454 case RTF_HEADER: 3455 case RTF_HEADERL: 3456 case RTF_HEADERR: 3457 case RTF_FOOTER: 3458 case RTF_FOOTERL: 3459 case RTF_FOOTERR: 3460 case RTF_FOOTERF: 3461 case RTF_HEADERF: 3462 ReadHeaderFooter(nToken, pPg); 3463 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen! 3464 break; 3465 case RTF_TEXTTOKEN: 3466 if (!DelCharAtEnd(aToken, ';' ).Len()) 3467 break; 3468 ASSERT(pPg, "Unexpected missing pPg"); 3469 if (pPg) 3470 { 3471 pPg->SetName(aToken); 3472 3473 // sollte es eine Vorlage aus dem Pool sein ?? 3474 sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(aToken, 3475 nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC); 3476 if (USHRT_MAX != n) 3477 { 3478 // dann setze bei der Neuen die entsp. PoolId 3479 pPg->SetPoolFmtId(n); 3480 } 3481 } 3482 break; 3483 case RTF_BRDBOX: 3484 if (3 == nNumOpenBrakets) 3485 { 3486 ReadBorderAttr(SkipToken(-2), 3487 (SfxItemSet&)pPgFmt->GetAttrSet()); 3488 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen! 3489 } 3490 break; 3491 case RTF_SHADOW: 3492 if( 3 == nNumOpenBrakets ) 3493 { 3494 ReadAttr( SkipToken( -2 ), (SfxItemSet*)&pPgFmt->GetAttrSet() ); 3495 --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen! 3496 } 3497 break; 3498 3499 3500 default: 3501 if( (nToken & ~0xff ) == RTF_SHADINGDEF ) 3502 ReadBackgroundAttr( nToken, (SfxItemSet&)pPgFmt->GetAttrSet() ); 3503 break; 3504 } 3505 } 3506 3507 3508 // setze jetzt noch bei allen die entsprechenden Follows !! 3509 // Die, die ueber die Tabelle eingelesen wurden und einen 3510 // Follow definiert haben, ist dieser als Tabposition im 3511 // Follow schon gesetzt. 3512 for( nPos = 0; nPos < pDoc->GetPageDescCnt(); ++nPos ) 3513 { 3514 SwPageDesc* pPgDsc = &pDoc->_GetPageDesc( nPos ); 3515 std::map< const SwPageDesc*, sal_uInt16 >::const_iterator aIter = 3516 aFollowMap.find( pPgDsc ); 3517 if (aIter != aFollowMap.end()) 3518 { 3519 if ((*aIter).second < pDoc->GetPageDescCnt()) 3520 pPgDsc->SetFollow(& const_cast<const SwDoc *>(pDoc)->GetPageDesc((*aIter).second)); 3521 } 3522 } 3523 3524 SetChkStyleAttr( bSaveChkStyleAttr ); 3525 3526 bInPgDscTbl = false; 3527 nAktPageDesc = 0; 3528 nAktFirstPageDesc = 0; 3529 bSwPageDesc = true; 3530 SkipToken( -1 ); 3531 } 3532 3533 // -------------- Methoden -------------------- 3534 3535 /* 3536 void SwRTFParser::ReadUnknownData() 3537 { 3538 SvRTFParser::ReadUnknownData(); 3539 } 3540 3541 void SwRTFParser::ReadOLEData() 3542 { 3543 SvRTFParser::ReadOLEData(); 3544 } 3545 */ 3546 3547 void SwRTFParser::ReadPrtData() 3548 { 3549 while( IsParserWorking() ) 3550 { 3551 int nToken = GetNextToken(); 3552 if( (RTF_TEXTTOKEN != nToken) && ('}' == nToken) ) 3553 break; 3554 } 3555 3556 SkipToken( -1 ); // schliessende Klammer wieder zurueck!! 3557 } 3558 3559 static const SwNodeIndex* SetHeader(SwFrmFmt* pHdFtFmt, sal_Bool bReuseOld) 3560 { 3561 ASSERT(pHdFtFmt, "Impossible, no header"); 3562 const SwFrmFmt* pExisting = bReuseOld ? 3563 pHdFtFmt->GetHeader().GetHeaderFmt() : 0; 3564 if (!pExisting) 3565 { 3566 //No existing header, create a new one 3567 pHdFtFmt->SetFmtAttr(SwFmtHeader(sal_True)); 3568 pExisting = pHdFtFmt->GetHeader().GetHeaderFmt(); 3569 } 3570 return pExisting->GetCntnt().GetCntntIdx(); 3571 } 3572 3573 static const SwNodeIndex* SetFooter(SwFrmFmt* pHdFtFmt, sal_Bool bReuseOld) 3574 { 3575 ASSERT(pHdFtFmt, "Impossible, no footer"); 3576 const SwFrmFmt* pExisting = bReuseOld ? 3577 pHdFtFmt->GetFooter().GetFooterFmt() : 0; 3578 if (!pExisting) 3579 { 3580 //No exist footer, create a new one 3581 pHdFtFmt->SetFmtAttr(SwFmtFooter(sal_True)); 3582 pExisting = pHdFtFmt->GetFooter().GetFooterFmt(); 3583 } 3584 return pExisting->GetCntnt().GetCntntIdx(); 3585 } 3586 3587 3588 void SwRTFParser::ReadHeaderFooter( int nToken, SwPageDesc* pPageDesc ) 3589 { 3590 ASSERT( RTF_FOOTNOTE == nToken || 3591 RTF_FLY_INPARA == nToken || 3592 pPageDesc, "PageDesc is missing" ); 3593 3594 bool bContainsParaCache = bContainsPara; 3595 // backup all important data 3596 SwPosition aSavePos( *pPam->GetPoint() ); 3597 SvxRTFItemStack aSaveStack(GetAttrStack()); 3598 GetAttrStack().clear(); 3599 3600 // save the fly array - after read, all flys may be set into 3601 // the header/footer 3602 SwFlySaveArr aSaveArray( 255 < aFlyArr.Count() ? aFlyArr.Count() : 255 ); 3603 aSaveArray.Insert( &aFlyArr, 0 ); 3604 aFlyArr.Remove( 0, aFlyArr.Count() ); 3605 sal_Bool bSetFlyInDoc = sal_True; 3606 3607 const SwNodeIndex* pSttIdx = 0; 3608 SwFrmFmt* pHdFtFmt = 0; 3609 SwTxtAttr* pTxtAttr = 0; 3610 int bDelFirstChar = sal_False; 3611 bool bOldIsFootnote = mbIsFootnote; 3612 sal_Bool bOldGrpStt = sal::static_int_cast< sal_Bool, int >(IsNewGroup()); 3613 3614 int nNumOpenBrakets = GetOpenBrakets() - 1; 3615 3616 switch( nToken ) 3617 { 3618 case RTF_FOOTNOTE: 3619 { 3620 bool bIsEndNote = RTF_FTNALT == GetNextToken(); 3621 if (!bIsEndNote) 3622 SkipToken(-1); 3623 3624 SwTxtNode* pTxtNd = pPam->GetNode()->GetTxtNode(); 3625 SwFmtFtn aFtnNote(bIsEndNote); 3626 xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex(); 3627 3628 if (nPos && !bFootnoteAutoNum) 3629 { 3630 pPam->GetPoint()->nContent--; 3631 nPos--; 3632 aFtnNote.SetNumStr( pTxtNd->GetTxt().GetChar( nPos ) ); 3633 ((String&)pTxtNd->GetTxt()).SetChar( nPos, CH_TXTATR_INWORD ); 3634 bDelFirstChar = sal_True; 3635 } 3636 3637 pTxtAttr = pTxtNd->InsertItem( aFtnNote, nPos, nPos, 3638 bDelFirstChar ? nsSetAttrMode::SETATTR_NOTXTATRCHR : 0 ); 3639 3640 ASSERT( pTxtAttr, "konnte die Fussnote nicht einfuegen/finden" ); 3641 3642 if( pTxtAttr ) 3643 pSttIdx = ((SwTxtFtn*)pTxtAttr)->GetStartNode(); 3644 mbIsFootnote = true; 3645 3646 // wurde an der Position ein Escapement aufgespannt, so entferne 3647 // das jetzt. Fussnoten sind bei uns immer hochgestellt. 3648 SvxRTFItemStackTypePtr pTmp = aSaveStack.empty() ? 0 : aSaveStack.back(); 3649 if( pTmp && pTmp->GetSttNodeIdx() == 3650 pPam->GetPoint()->nNode.GetIndex() && 3651 pTmp->GetSttCnt() == nPos ) 3652 pTmp->GetAttrSet().ClearItem( RES_CHRATR_ESCAPEMENT ); 3653 } 3654 break; 3655 3656 case RTF_FLY_INPARA: 3657 { 3658 xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex(); 3659 SfxItemSet aSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN, 3660 RES_FRMATR_END-1 ); 3661 aSet.Put( SwFmtAnchor( FLY_AS_CHAR )); 3662 pHdFtFmt = pDoc->MakeFlySection( FLY_AS_CHAR, 3663 pPam->GetPoint(), &aSet ); 3664 3665 pTxtAttr = pPam->GetNode()->GetTxtNode()->GetTxtAttrForCharAt( 3666 nPos, RES_TXTATR_FLYCNT ); 3667 ASSERT( pTxtAttr, "konnte den Fly nicht einfuegen/finden" ); 3668 3669 pSttIdx = pHdFtFmt->GetCntnt().GetCntntIdx(); 3670 bSetFlyInDoc = sal_False; 3671 } 3672 break; 3673 3674 case RTF_HEADERF: 3675 case RTF_HEADER: 3676 pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_HEADERSHARE) ); 3677 pHdFtFmt = &pPageDesc->GetMaster(); 3678 pSttIdx = SetHeader( pHdFtFmt, sal_False ); 3679 break; 3680 3681 case RTF_HEADERL: 3682 // we cannot have left or right, must have always both 3683 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL)); 3684 SetHeader( pPageDesc->GetRightFmt(), sal_True ); 3685 pHdFtFmt = pPageDesc->GetLeftFmt(); 3686 pSttIdx = SetHeader(pHdFtFmt, sal_False ); 3687 break; 3688 3689 case RTF_HEADERR: 3690 // we cannot have left or right, must have always both 3691 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL)); 3692 SetHeader( pPageDesc->GetLeftFmt(), sal_True ); 3693 pHdFtFmt = pPageDesc->GetRightFmt(); 3694 pSttIdx = SetHeader(pHdFtFmt, sal_False ); 3695 break; 3696 3697 case RTF_FOOTERF: 3698 case RTF_FOOTER: 3699 pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_FOOTERSHARE) ); 3700 pHdFtFmt = &pPageDesc->GetMaster(); 3701 pSttIdx = SetFooter(pHdFtFmt, sal_False ); 3702 break; 3703 3704 case RTF_FOOTERL: 3705 // we cannot have left or right, must have always both 3706 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL)); 3707 SetFooter( pPageDesc->GetRightFmt(), sal_True ); 3708 pHdFtFmt = pPageDesc->GetLeftFmt(); 3709 pSttIdx = SetFooter(pHdFtFmt, sal_False ); 3710 break; 3711 3712 case RTF_FOOTERR: 3713 // we cannot have left or right, must have always both 3714 pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL)); 3715 SetFooter( pPageDesc->GetLeftFmt(), sal_True ); 3716 pHdFtFmt = pPageDesc->GetRightFmt(); 3717 pSttIdx = SetFooter(pHdFtFmt, sal_False ); 3718 break; 3719 } 3720 3721 sal_uInt16 nOldFlyArrCnt = aFlyArr.Count(); 3722 if( !pSttIdx ) 3723 SkipGroup(); 3724 else 3725 { 3726 // es ist auf jedenfall jetzt ein TextNode im Kopf/Fusszeilen-Bereich 3727 // vorhanden. Dieser muss jetzt nur noch gefunden und der neue Cursor 3728 // dort hinein gesetzt werden. 3729 SwCntntNode *pNode = pDoc->GetNodes()[ pSttIdx->GetIndex()+1 ]-> 3730 GetCntntNode(); 3731 3732 // immer ans Ende der Section einfuegen !! 3733 pPam->GetPoint()->nNode = *pNode->EndOfSectionNode(); 3734 pPam->Move( fnMoveBackward ); 3735 3736 SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 ); 3737 if( !pColl ) 3738 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); 3739 pDoc->SetTxtFmtColl( *pPam, pColl ); 3740 3741 SetNewGroup( sal_True ); 3742 3743 while( !( nNumOpenBrakets == GetOpenBrakets() && !GetStackPos()) && IsParserWorking() ) 3744 { 3745 switch( nToken = GetNextToken() ) 3746 { 3747 case RTF_U: 3748 if( bDelFirstChar ) 3749 { 3750 bDelFirstChar = sal_False; 3751 nToken = 0; 3752 } 3753 break; 3754 3755 case RTF_TEXTTOKEN: 3756 if( bDelFirstChar ) 3757 { 3758 if( !aToken.Erase( 0, 1 ).Len() ) 3759 nToken = 0; 3760 bDelFirstChar = sal_False; 3761 } 3762 break; 3763 } 3764 if( nToken ) 3765 NextToken( nToken ); 3766 } 3767 3768 SetAllAttrOfStk(); 3769 if( aFlyArr.Count() && bSetFlyInDoc ) 3770 SetFlysInDoc(); 3771 3772 // sollte der letze Node leer sein, dann loesche ihn 3773 // (\par heisst ja Absatzende und nicht neuer Absatz!) 3774 DelLastNode(); 3775 } 3776 3777 // vom FlyFmt noch die richtigen Attribute setzen 3778 if( pTxtAttr && RES_TXTATR_FLYCNT == pTxtAttr->Which() ) 3779 { 3780 // is add a new fly ? 3781 if( nOldFlyArrCnt < aFlyArr.Count() ) 3782 { 3783 SwFlySave* pFlySave = aFlyArr[ aFlyArr.Count()-1 ]; 3784 pFlySave->aFlySet.ClearItem( RES_ANCHOR ); 3785 pHdFtFmt->SetFmtAttr( pFlySave->aFlySet ); 3786 aFlyArr.DeleteAndDestroy( aFlyArr.Count() - 1 ); 3787 } 3788 else 3789 { 3790 // no, so remove the created textattribute 3791 SwFrmFmt* pFlyFmt = pTxtAttr->GetFlyCnt().GetFrmFmt(); 3792 // remove the pam from the flynode 3793 *pPam->GetPoint() = aSavePos; 3794 pDoc->DelLayoutFmt( pFlyFmt ); 3795 } 3796 } 3797 3798 bFootnoteAutoNum = sal_False; // default auf aus! 3799 3800 // und alles wieder zurueck 3801 *pPam->GetPoint() = aSavePos; 3802 if (mbIsFootnote) 3803 SetNewGroup( bOldGrpStt ); // Status wieder zurueck 3804 else 3805 SetNewGroup( sal_False ); // { - Klammer war kein Group-Start! 3806 mbIsFootnote = bOldIsFootnote; 3807 GetAttrStack() = aSaveStack; 3808 3809 aFlyArr.Insert( &aSaveArray, 0 ); 3810 aSaveArray.Remove( 0, aSaveArray.Count() ); 3811 bContainsPara = bContainsParaCache; 3812 } 3813 3814 void SwRTFParser::SetSwgValues( SfxItemSet& rSet ) 3815 { 3816 const SfxPoolItem* pItem; 3817 // Escapement korrigieren 3818 if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ESCAPEMENT, sal_False, &pItem )) 3819 { 3820 /* prozentuale Veraenderung errechnen ! 3821 * Formel : (FontSize * 1/20 ) pts Escapement * 2 3822 * ----------------------- = ---------------- 3823 * 100% x 3824 */ 3825 3826 // die richtige 3827 long nEsc = ((SvxEscapementItem*)pItem)->GetEsc(); 3828 3829 // automatische Ausrichtung wurde schon richtig berechnet 3830 if( DFLT_ESC_AUTO_SUPER != nEsc && DFLT_ESC_AUTO_SUB != nEsc ) 3831 { 3832 const SvxFontHeightItem& rFH = GetSize( rSet ); 3833 nEsc *= 1000L; 3834 if(rFH.GetHeight()) nEsc /= long(rFH.GetHeight()); // #i77256# 3835 3836 SvxEscapementItem aEsc( (short) nEsc, 3837 ((SvxEscapementItem*)pItem)->GetProp(), RES_CHRATR_ESCAPEMENT); 3838 rSet.Put( aEsc ); 3839 } 3840 } 3841 3842 // TabStops anpassen 3843 if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_TABSTOP, sal_False, &pItem )) 3844 { 3845 const SvxLRSpaceItem& rLR = GetLRSpace( rSet ); 3846 SvxTabStopItem aTStop( *(SvxTabStopItem*)pItem ); 3847 3848 long nOffset = rLR.GetTxtLeft(); 3849 if( nOffset ) 3850 { 3851 // Tabs anpassen !! 3852 SvxTabStop* pTabs = (SvxTabStop*)aTStop.GetStart(); 3853 for( sal_uInt16 n = aTStop.Count(); n; --n, ++pTabs) 3854 if( SVX_TAB_ADJUST_DEFAULT != pTabs->GetAdjustment() ) 3855 pTabs->GetTabPos() -= nOffset; 3856 3857 // negativer Einzug, dann auf 0 Pos einen Tab setzen 3858 if( rLR.GetTxtFirstLineOfst() < 0 ) 3859 aTStop.Insert( SvxTabStop() ); 3860 } 3861 3862 if( !aTStop.Count() ) 3863 { 3864 const SvxTabStopItem& rDflt = (const SvxTabStopItem&)rSet. 3865 GetPool()->GetDefaultItem(RES_PARATR_TABSTOP); 3866 if( rDflt.Count() ) 3867 aTStop.Insert( &rDflt, 0 ); 3868 } 3869 rSet.Put( aTStop ); 3870 } 3871 else if( SFX_ITEM_SET == rSet.GetItemState( RES_LR_SPACE, sal_False, &pItem ) 3872 && ((SvxLRSpaceItem*)pItem)->GetTxtFirstLineOfst() < 0 ) 3873 { 3874 // negativer Einzug, dann auf 0 Pos einen Tab setzen 3875 rSet.Put( SvxTabStopItem( 1, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP )); 3876 } 3877 3878 // NumRules anpassen 3879 if( !bStyleTabValid && 3880 SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_NUMRULE, sal_False, &pItem )) 3881 { 3882 // dann steht im Namen nur ein Verweis in das ListArray 3883 SwNumRule* pRule = GetNumRuleOfListNo( ((SwNumRuleItem*)pItem)-> 3884 GetValue().ToInt32() ); 3885 if( pRule ) 3886 rSet.Put( SwNumRuleItem( pRule->GetName() )); 3887 else 3888 rSet.ClearItem( RES_PARATR_NUMRULE ); 3889 3890 } 3891 3892 3893 /* 3894 ???????????????????????????????????????????????????????????????????? 3895 ?? muss die LineSpacing Hoehe 200Twip betragen ?? 3896 ?? in rtfitem.hxx wird es auf 0 defaultet. Wenn ja, dann muss hier 3897 ?? ein neues Item gesetzt werden!!!! 3898 ???????????????????????????????????????????????????????????????????? 3899 3900 // LineSpacing korrigieren 3901 if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_LINESPACING, sal_False, &pItem )) 3902 { 3903 const SvxLineSpacingItem* pLS = (const SvxLineSpacingItem*)pItem; 3904 SvxLineSpacingItem aNew; 3905 3906 aNew.SetInterLineSpace( pLS->GetInterLineSpace() ); 3907 aNew.GetLineSpaceRule() = pLS->GetLineSpaceRule(); 3908 aNew.SetPropLineSpace( pLS->GetPropLineSpace() ); 3909 aNew.GetInterLineSpaceRule() = pLS->GetInterLineSpaceRule(); 3910 3911 rSet.Put( aNew ); 3912 } 3913 ?????????????????????????????????????????????????????????????????? */ 3914 3915 } 3916 3917 3918 SwTxtFmtColl* SwRTFParser::MakeColl(const String& rName, sal_uInt16 nPos, 3919 sal_uInt8 nOutlineLevel, bool& rbCollExist) 3920 { 3921 if( sal_uInt8(-1) == nOutlineLevel ) 3922 //nOutlineLevel = NO_NUMBERING; 3923 nOutlineLevel = MAXLEVEL;//#outline level,zhaojianwei 3924 3925 rbCollExist = false; 3926 SwTxtFmtColl* pColl; 3927 String aNm( rName ); 3928 if( !aNm.Len() ) 3929 { 3930 ASSERT(!this, "not a bug, but I (cmc) want to see an example of this"); 3931 if( !nPos ) 3932 { 3933 pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); 3934 //pColl->SetOutlineLevel( nOutlineLevel ); //#outline level,removed by zhaojianwei 3935 if(nOutlineLevel < MAXLEVEL ) //->add by zhaojianwei 3936 pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel ); 3937 else 3938 pColl->DeleteAssignmentToListLevelOfOutlineStyle(); //<-end,zhaojianwei 3939 return pColl; 3940 } 3941 3942 // erzeuge einen Namen 3943 aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" )); 3944 aNm += String::CreateFromInt32( nPos ); 3945 aNm += ')'; 3946 } 3947 ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName); 3948 sw::util::ParaStyleMapper::StyleResult aResult = 3949 maParaStyleMapper.GetStyle(rName, eSti); 3950 pColl = aResult.first; 3951 rbCollExist = aResult.second; 3952 if (IsNewDoc() && rbCollExist) 3953 { 3954 // --> OD 2007-01-25 #i73790# - method renamed 3955 pColl->ResetAllFmtAttr(); 3956 // <-- 3957 rbCollExist = false; 3958 } 3959 3960 if (!rbCollExist) 3961 { 3962 //pColl->SetOutlineLevel( nOutlineLevel ); //#outline level,removed by zhaojianwei 3963 if(nOutlineLevel < MAXLEVEL) //->add by zhaojianwei 3964 pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel ); 3965 else 3966 pColl->DeleteAssignmentToListLevelOfOutlineStyle(); //<-end,zhaojianwei 3967 } 3968 3969 return pColl; 3970 } 3971 3972 SwCharFmt* SwRTFParser::MakeCharFmt(const String& rName, sal_uInt16 nPos, 3973 int& rbCollExist) 3974 { 3975 rbCollExist = sal_False; 3976 SwCharFmt* pFmt; 3977 String aNm( rName ); 3978 if( !aNm.Len() ) 3979 { 3980 ASSERT(!this, "not a bug, but I (cmc) want to see an example of this"); 3981 aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" )); 3982 aNm += String::CreateFromInt32( nPos ); 3983 aNm += ')'; 3984 } 3985 3986 ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName); 3987 sw::util::CharStyleMapper::StyleResult aResult = 3988 maCharStyleMapper.GetStyle(rName, eSti); 3989 pFmt = aResult.first; 3990 rbCollExist = aResult.second; 3991 if (IsNewDoc() && rbCollExist) 3992 { 3993 // --> OD 2007-01-25 #i73790# - method renamed 3994 pFmt->ResetAllFmtAttr(); 3995 // <-- 3996 rbCollExist = false; 3997 } 3998 return pFmt; 3999 } 4000 4001 void SwRTFParser::SetStyleAttr( SfxItemSet& rCollSet, 4002 const SfxItemSet& rStyleSet, 4003 const SfxItemSet& rDerivedSet ) 4004 { 4005 rCollSet.Put( rStyleSet ); 4006 if( rDerivedSet.Count() ) 4007 { 4008 // suche alle Attribute, die neu gesetzt werden: 4009 const SfxPoolItem* pItem; 4010 SfxItemIter aIter( rDerivedSet ); 4011 sal_uInt16 nWhich = aIter.GetCurItem()->Which(); 4012 while( sal_True ) 4013 { 4014 switch( rStyleSet.GetItemState( nWhich, sal_False, &pItem ) ) 4015 { 4016 case SFX_ITEM_DEFAULT: 4017 // auf default zuruecksetzen 4018 if( RES_FRMATR_END > nWhich ) 4019 rCollSet.Put( rCollSet.GetPool()->GetDefaultItem( nWhich )); 4020 break; 4021 case SFX_ITEM_SET: 4022 if( *pItem == *aIter.GetCurItem() ) // gleiches Attribut? 4023 // definition kommt aus dem Parent 4024 rCollSet.ClearItem( nWhich ); // loeschen 4025 break; 4026 } 4027 4028 if( aIter.IsAtEnd() ) 4029 break; 4030 nWhich = aIter.NextItem()->Which(); 4031 } 4032 } 4033 // und jetzt noch auf unsere Werte abgleichen 4034 SetSwgValues( rCollSet ); 4035 } 4036 4037 SwTxtFmtColl* SwRTFParser::MakeStyle( sal_uInt16 nNo, const SvxRTFStyleType& rStyle) 4038 { 4039 bool bCollExist; 4040 SwTxtFmtColl* pColl = MakeColl( rStyle.sName, sal_uInt16(nNo), 4041 rStyle.nOutlineNo, bCollExist); 4042 aTxtCollTbl.Insert( nNo, pColl ); 4043 4044 // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen 4045 if( bCollExist ) 4046 return pColl; 4047 4048 sal_uInt16 nStyleNo = rStyle.nBasedOn; 4049 if( rStyle.bBasedOnIsSet && nStyleNo != nNo ) 4050 { 4051 SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo ); 4052 SwTxtFmtColl* pDerivedColl = aTxtCollTbl.Get( nStyleNo ); 4053 if( !pDerivedColl ) // noch nicht vorhanden, also anlegen 4054 { 4055 // ist die ueberhaupt als Style vorhanden ? 4056 pDerivedColl = pDerivedStyle 4057 ? MakeStyle( nStyleNo, *pDerivedStyle ) 4058 : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); 4059 } 4060 4061 if( pColl == pDerivedColl ) 4062 ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet ); 4063 else 4064 { 4065 pColl->SetDerivedFrom( pDerivedColl ); 4066 4067 // setze die richtigen Attribute 4068 const SfxItemSet* pDerivedSet; 4069 if( pDerivedStyle ) 4070 pDerivedSet = &pDerivedStyle->aAttrSet; 4071 else 4072 pDerivedSet = &pDerivedColl->GetAttrSet(); 4073 4074 SetStyleAttr( (SfxItemSet&)pColl->GetAttrSet(), 4075 rStyle.aAttrSet, *pDerivedSet ); 4076 } 4077 } 4078 else 4079 ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet ); 4080 4081 4082 nStyleNo = rStyle.nNext; 4083 if( nStyleNo != nNo ) 4084 { 4085 SwTxtFmtColl* pNext = aTxtCollTbl.Get( nStyleNo ); 4086 if( !pNext ) // noch nicht vorhanden, also anlegen 4087 { 4088 // ist die ueberhaupt als Style vorhanden ? 4089 SvxRTFStyleType* pMkStyle = GetStyleTbl().Get( nStyleNo ); 4090 pNext = pMkStyle 4091 ? MakeStyle( nStyleNo, *pMkStyle ) 4092 : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); 4093 } 4094 pColl->SetNextTxtFmtColl( *pNext ); 4095 } 4096 return pColl; 4097 } 4098 4099 SwCharFmt* SwRTFParser::MakeCharStyle( sal_uInt16 nNo, const SvxRTFStyleType& rStyle ) 4100 { 4101 int bCollExist; 4102 SwCharFmt* pFmt = MakeCharFmt( rStyle.sName, sal_uInt16(nNo), bCollExist ); 4103 aCharFmtTbl.Insert( nNo, pFmt ); 4104 4105 // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen 4106 if( bCollExist ) 4107 return pFmt; 4108 4109 sal_uInt16 nStyleNo = rStyle.nBasedOn; 4110 if( rStyle.bBasedOnIsSet && nStyleNo != nNo ) 4111 { 4112 SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo ); 4113 SwCharFmt* pDerivedFmt = aCharFmtTbl.Get( nStyleNo ); 4114 if( !pDerivedFmt ) // noch nicht vorhanden, also anlegen 4115 { 4116 // ist die ueberhaupt als Style vorhanden ? 4117 pDerivedFmt = pDerivedStyle 4118 ? MakeCharStyle( nStyleNo, *pDerivedStyle ) 4119 : pDoc->GetDfltCharFmt(); 4120 } 4121 4122 if( pFmt == pDerivedFmt ) 4123 ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet ); 4124 else 4125 { 4126 pFmt->SetDerivedFrom( pDerivedFmt ); 4127 4128 // setze die richtigen Attribute 4129 const SfxItemSet* pDerivedSet; 4130 if( pDerivedStyle ) 4131 pDerivedSet = &pDerivedStyle->aAttrSet; 4132 else 4133 pDerivedSet = &pDerivedFmt->GetAttrSet(); 4134 4135 SetStyleAttr( (SfxItemSet&)pFmt->GetAttrSet(), 4136 rStyle.aAttrSet, *pDerivedSet ); 4137 } 4138 } 4139 else 4140 ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet ); 4141 4142 return pFmt; 4143 } 4144 4145 // loesche den letzten Node (Tabelle/Fly/Ftn/..) 4146 void SwRTFParser::DelLastNode() 4147 { 4148 // sollte der letze Node leer sein, dann loesche ihn 4149 // (\par heisst ja Absatzende und nicht neuer Absatz!) 4150 4151 if( !pPam->GetPoint()->nContent.GetIndex() ) 4152 { 4153 sal_uLong nNodeIdx = pPam->GetPoint()->nNode.GetIndex(); 4154 SwCntntNode* pCNd = pDoc->GetNodes()[ nNodeIdx ]->GetCntntNode(); 4155 // paragraphs with page break information are not empty! see #117914# topic 1) 4156 if(const SfxPoolItem* pItem=&(pCNd->GetAttr( RES_PAGEDESC, sal_False))) 4157 { 4158 SwFmtPageDesc* pPageDescItem = ((SwFmtPageDesc*)pItem); 4159 if (pPageDescItem->GetPageDesc()!=NULL) 4160 return; 4161 } 4162 4163 if( pCNd && pCNd->StartOfSectionIndex()+2 < 4164 pCNd->EndOfSectionIndex() ) 4165 { 4166 if( !GetAttrStack().empty() ) 4167 { 4168 // Attribut Stack-Eintraege, muessen ans Ende des vorherigen 4169 // Nodes verschoben werden. 4170 sal_Bool bMove = sal_False; 4171 for( size_t n = GetAttrStack().size(); n; ) 4172 { 4173 SvxRTFItemStackType* pStkEntry = (SvxRTFItemStackType*) 4174 GetAttrStack()[ --n ]; 4175 if( nNodeIdx == pStkEntry->GetSttNode().GetIdx() ) 4176 { 4177 if( !bMove ) 4178 { 4179 pPam->Move( fnMoveBackward ); 4180 bMove = sal_True; 4181 } 4182 pStkEntry->SetStartPos( SwxPosition( pPam ) ); 4183 } 4184 } 4185 if( bMove ) 4186 pPam->Move( fnMoveForward ); 4187 } 4188 pPam->GetPoint()->nContent.Assign( 0, 0 ); 4189 pPam->SetMark(); 4190 pPam->DeleteMark(); 4191 4192 pDoc->GetNodes().Delete( pPam->GetPoint()->nNode ); 4193 } 4194 } 4195 } 4196 4197 // fuer Tokens, die im ReadAttr nicht ausgewertet werden 4198 void SwRTFParser::UnknownAttrToken( int nToken, SfxItemSet* pSet ) 4199 { 4200 switch( nToken ) 4201 { 4202 case RTF_INTBL: 4203 { 4204 if( !pTableNode ) // Tabelle nicht mehr vorhanden ? 4205 NewTblLine(); // evt. Line copieren 4206 else 4207 { 4208 static int _do=0; //$flr See #117881# for explanation. 4209 // Crsr nicht mehr in der Tabelle ? 4210 if( !pPam->GetNode()->FindTableNode() && _do ) 4211 { 4212 sal_uLong nOldPos = pPam->GetPoint()->nNode.GetIndex(); 4213 4214 // dann wieder in die letzte Box setzen 4215 // (kann durch einlesen von Flys geschehen!) 4216 pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode(); 4217 pPam->Move( fnMoveBackward ); 4218 4219 // alle Attribute, die schon auf den nachfolgen zeigen 4220 // auf die neue Box umsetzen !! 4221 SvxRTFItemStack& rAttrStk = GetAttrStack(); 4222 const SvxRTFItemStackType* pStk; 4223 for( size_t n = 0; n < rAttrStk.size(); ++n ) 4224 if( ( pStk = rAttrStk[ n ])->GetSttNodeIdx() == nOldPos && 4225 !pStk->GetSttCnt() ) 4226 ((SvxRTFItemStackType*)pStk)->SetStartPos( SwxPosition( pPam ) ); 4227 } 4228 } 4229 } 4230 break; 4231 4232 case RTF_PAGEBB: 4233 { 4234 pSet->Put( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK )); 4235 } 4236 break; 4237 4238 case RTF_PGBRK: 4239 { 4240 pSet->Put( SvxFmtBreakItem( 1 == nTokenValue ? 4241 SVX_BREAK_PAGE_BOTH : SVX_BREAK_PAGE_AFTER, RES_BREAK )); 4242 } 4243 break; 4244 4245 case RTF_PGDSCNO: 4246 if( IsNewDoc() && bSwPageDesc && 4247 sal_uInt16(nTokenValue) < pDoc->GetPageDescCnt() ) 4248 { 4249 const SwPageDesc* pPgDsc = &const_cast<const SwDoc *>(pDoc) 4250 ->GetPageDesc( (sal_uInt16)nTokenValue ); 4251 pDoc->InsertPoolItem( *pPam, SwFmtPageDesc( pPgDsc ), 0); 4252 } 4253 break; 4254 case RTF_CS: 4255 { 4256 SwCharFmt* pFmt = aCharFmtTbl.Get( nTokenValue ); 4257 if( pFmt ) 4258 pSet->Put( SwFmtCharFmt( pFmt )); 4259 } 4260 break; 4261 4262 case RTF_LS: 4263 if( -1 != nTokenValue ) 4264 { 4265 if( bStyleTabValid ) 4266 { 4267 // dann ist auch die ListTabelle gueltig, also suche die 4268 // enstprechende NumRule 4269 SwNumRule* pRule = GetNumRuleOfListNo( nTokenValue ); 4270 if( pRule ) 4271 pSet->Put( SwNumRuleItem( pRule->GetName() )); 4272 4273 if( SFX_ITEM_SET != pSet->GetItemState( FN_PARAM_NUM_LEVEL, sal_False )) 4274 pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 )); 4275 } 4276 else 4277 { 4278 // wir sind in der Style-Definitions - Phase. Der Name 4279 // wird dann spaeter umgesetzt 4280 //#117891# pSet->Put( SwNumRuleItem( String::CreateFromInt32( nTokenValue ))); 4281 } 4282 4283 } 4284 break; 4285 4286 case RTF_ILVL: 4287 case RTF_SOUTLVL: 4288 { 4289 sal_uInt8 nLevel = MAXLEVEL <= nTokenValue ? MAXLEVEL - 1 4290 : sal_uInt8( nTokenValue ); 4291 pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, nLevel )); 4292 } 4293 break; 4294 4295 /* 4296 case RTF_SBYS: 4297 case RTF_EXPND: 4298 case RTF_KEEP: 4299 case RTF_KEEPN: 4300 */ 4301 4302 } 4303 } 4304 4305 void SwRTFParser::ReadInfo( const sal_Char* pChkForVerNo ) 4306 { 4307 sal_Char __READONLY_DATA aChkForVerNo[] = "StarWriter"; 4308 4309 // falls nicht schon was vorgegeben wurde, setzen wir unseren Namen 4310 // rein. Wenn das im Kommentar match, wird im Parser die VersionNummer 4311 // gelesen und gesetzt 4312 if( !pChkForVerNo ) 4313 pChkForVerNo = aChkForVerNo; 4314 4315 SvxRTFParser::ReadInfo( pChkForVerNo ); 4316 } 4317 4318 void SwRTFParser::ReadUserProperties() 4319 { 4320 // For now we don't support user properties but at least the parser is here. 4321 // At the moment it just swallows the tokens to prevent them being displayed 4322 int nNumOpenBrakets = 1, nToken; 4323 4324 while( nNumOpenBrakets && IsParserWorking() ) 4325 { 4326 switch( nToken = GetNextToken() ) 4327 { 4328 case '}': 4329 --nNumOpenBrakets; 4330 break; 4331 case '{': 4332 { 4333 if( RTF_IGNOREFLAG != GetNextToken() ) 4334 nToken = SkipToken( -1 ); 4335 else if( RTF_UNKNOWNCONTROL != GetNextToken() ) 4336 nToken = SkipToken( -2 ); 4337 else 4338 { 4339 // gleich herausfiltern 4340 ReadUnknownData(); 4341 nToken = GetNextToken(); 4342 if( '}' != nToken ) 4343 eState = SVPAR_ERROR; 4344 break; 4345 } 4346 ++nNumOpenBrakets; 4347 } 4348 break; 4349 4350 case RTF_PROPNAME: 4351 SkipGroup(); 4352 break; 4353 4354 case RTF_PROPTYPE: 4355 break; 4356 4357 case RTF_STATICVAL: 4358 SkipGroup(); 4359 break; 4360 4361 // default: 4362 } 4363 } 4364 4365 SkipToken( -1 ); 4366 } 4367 4368 4369 #ifdef USED 4370 void SwRTFParser::SaveState( int nToken ) 4371 { 4372 SvxRTFParser::SaveState( nToken ); 4373 } 4374 4375 void SwRTFParser::RestoreState() 4376 { 4377 SvxRTFParser::RestoreState(); 4378 } 4379 #endif 4380 4381 /**/ 4382 4383 BookmarkPosition::BookmarkPosition(const SwPaM &rPaM) 4384 : maMkNode(rPaM.GetMark()->nNode), 4385 mnMkCntnt(rPaM.GetMark()->nContent.GetIndex()) 4386 { 4387 } 4388 4389 BookmarkPosition::BookmarkPosition(const BookmarkPosition &rEntry) 4390 : maMkNode(rEntry.maMkNode), mnMkCntnt(rEntry.mnMkCntnt) 4391 { 4392 } 4393 4394 bool BookmarkPosition::operator==(const BookmarkPosition rhs) 4395 { 4396 return(maMkNode.GetIndex() == rhs.maMkNode.GetIndex() && mnMkCntnt == rhs.mnMkCntnt); 4397 } 4398 4399 sal_uLong SwNodeIdx::GetIdx() const 4400 { 4401 return aIdx.GetIndex(); 4402 } 4403 4404 SvxNodeIdx* SwNodeIdx::Clone() const 4405 { 4406 return new SwNodeIdx( aIdx ); 4407 } 4408 4409 SvxPosition* SwxPosition::Clone() const 4410 { 4411 return new SwxPosition( pPam ); 4412 } 4413 4414 SvxNodeIdx* SwxPosition::MakeNodeIdx() const 4415 { 4416 return new SwNodeIdx( pPam->GetPoint()->nNode ); 4417 } 4418 4419 sal_uLong SwxPosition::GetNodeIdx() const 4420 { 4421 return pPam->GetPoint()->nNode.GetIndex(); 4422 } 4423 4424 xub_StrLen SwxPosition::GetCntIdx() const 4425 { 4426 return pPam->GetPoint()->nContent.GetIndex(); 4427 } 4428 4429 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 4430