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 27 28 #define _ZFORLIST_DECLARE_TABLE 29 #define _SVSTDARR_USHORTSSORT 30 #define _SVSTDARR_USHORTS 31 #include <hintids.hxx> 32 #include <rtl/logfile.hxx> 33 #include <svl/itemiter.hxx> 34 #include <sfx2/app.hxx> 35 #include <editeng/tstpitem.hxx> 36 #include <editeng/eeitem.hxx> 37 #include <editeng/langitem.hxx> 38 #include <editeng/lrspitem.hxx> 39 #include <editeng/brkitem.hxx> 40 #include <svl/whiter.hxx> 41 #ifndef _ZFORLIST_HXX //autogen 42 #define _ZFORLIST_DECLARE_TABLE 43 #include <svl/zforlist.hxx> 44 #endif 45 #include <comphelper/processfactory.hxx> 46 #include <unotools/misccfg.hxx> 47 #include <com/sun/star/i18n/WordType.hdl> 48 #include <fmtpdsc.hxx> 49 #include <fmthdft.hxx> 50 #include <fmtcntnt.hxx> 51 #include <frmatr.hxx> 52 #include <doc.hxx> 53 #include <IDocumentUndoRedo.hxx> 54 #include <rootfrm.hxx> 55 #include <pagefrm.hxx> 56 #include <hints.hxx> // fuer SwHyphenBug (in SetDefault) 57 #include <ndtxt.hxx> 58 #include <pam.hxx> 59 #include <UndoCore.hxx> 60 #include <UndoAttribute.hxx> 61 #include <ndgrf.hxx> 62 #include <pagedesc.hxx> // Fuer Sonderbehandlung in InsFrmFmt 63 #include <rolbck.hxx> // Undo-Attr 64 #include <mvsave.hxx> // servieren: Veraenderungen erkennen 65 #include <txatbase.hxx> 66 #include <swtable.hxx> 67 #include <swtblfmt.hxx> 68 #include <charfmt.hxx> 69 #include <docary.hxx> 70 #include <paratr.hxx> 71 #include <redline.hxx> 72 #include <reffld.hxx> 73 #include <txtinet.hxx> 74 #include <fmtinfmt.hxx> 75 #include <breakit.hxx> 76 #include <SwStyleNameMapper.hxx> 77 #include <fmtautofmt.hxx> 78 #include <istyleaccess.hxx> 79 #include <SwUndoFmt.hxx> 80 #include <docsh.hxx> 81 82 using namespace ::com::sun::star::i18n; 83 using namespace ::com::sun::star::lang; 84 using namespace ::com::sun::star::uno; 85 86 SV_IMPL_PTRARR(SwFrmFmts,SwFrmFmtPtr) 87 SV_IMPL_PTRARR(SwCharFmts,SwCharFmtPtr) 88 89 //Spezifische Frameformate (Rahmen) 90 SV_IMPL_PTRARR(SwSpzFrmFmts,SwFrmFmtPtr) 91 92 /* 93 * interne Funktionen 94 */ 95 96 sal_Bool SetTxtFmtCollNext( const SwTxtFmtCollPtr& rpTxtColl, void* pArgs ) 97 { 98 SwTxtFmtColl *pDel = (SwTxtFmtColl*) pArgs; 99 if ( &rpTxtColl->GetNextTxtFmtColl() == pDel ) 100 { 101 rpTxtColl->SetNextTxtFmtColl( *rpTxtColl ); 102 } 103 return sal_True; 104 } 105 106 /* 107 * Zuruecksetzen der harten Formatierung fuer Text 108 */ 109 110 // Uebergabeparameter fuer _Rst und lcl_SetTxtFmtColl 111 struct ParaRstFmt 112 { 113 SwFmtColl* pFmtColl; 114 SwHistory* pHistory; 115 const SwPosition *pSttNd, *pEndNd; 116 const SfxItemSet* pDelSet; 117 sal_uInt16 nWhich; 118 bool bReset; 119 bool bResetListAttrs; 120 bool bResetAll; 121 bool bInclRefToxMark; 122 123 ParaRstFmt( const SwPosition* pStt, const SwPosition* pEnd, 124 SwHistory* pHst, sal_uInt16 nWhch = 0, const SfxItemSet* pSet = 0 ) 125 : pFmtColl(0), 126 pHistory(pHst), 127 pSttNd(pStt), 128 pEndNd(pEnd), 129 pDelSet(pSet), 130 nWhich(nWhch), 131 bReset( false ), 132 bResetListAttrs( false ), 133 bResetAll( true ), 134 bInclRefToxMark( false ) 135 { 136 } 137 138 ParaRstFmt( SwHistory* pHst ) 139 : pFmtColl(0), 140 pHistory(pHst), 141 pSttNd(0), 142 pEndNd(0), 143 pDelSet(0), 144 nWhich(0), 145 bReset( false ), 146 bResetListAttrs( false ), 147 bResetAll( true ), 148 bInclRefToxMark( false ) 149 { 150 } 151 }; 152 153 /* in pArgs steht die ChrFmtTablle vom Dokument 154 * (wird bei Selectionen am Start/Ende und bei keiner SSelection benoetigt) 155 */ 156 157 sal_Bool lcl_RstTxtAttr( const SwNodePtr& rpNd, void* pArgs ) 158 { 159 ParaRstFmt* pPara = (ParaRstFmt*)pArgs; 160 SwTxtNode * pTxtNode = (SwTxtNode*)rpNd->GetTxtNode(); 161 if( pTxtNode && pTxtNode->GetpSwpHints() ) 162 { 163 SwIndex aSt( pTxtNode, 0 ); 164 sal_uInt16 nEnd = pTxtNode->Len(); 165 166 if( &pPara->pSttNd->nNode.GetNode() == pTxtNode && 167 pPara->pSttNd->nContent.GetIndex() ) 168 aSt = pPara->pSttNd->nContent.GetIndex(); 169 170 if( &pPara->pEndNd->nNode.GetNode() == rpNd ) 171 nEnd = pPara->pEndNd->nContent.GetIndex(); 172 173 if( pPara->pHistory ) 174 { 175 // fuers Undo alle Attribute sichern 176 SwRegHistory aRHst( *pTxtNode, pPara->pHistory ); 177 pTxtNode->GetpSwpHints()->Register( &aRHst ); 178 pTxtNode->RstTxtAttr( aSt, nEnd - aSt.GetIndex(), pPara->nWhich, 179 pPara->pDelSet, pPara->bInclRefToxMark ); 180 if( pTxtNode->GetpSwpHints() ) 181 pTxtNode->GetpSwpHints()->DeRegister(); 182 } 183 else 184 pTxtNode->RstTxtAttr( aSt, nEnd - aSt.GetIndex(), pPara->nWhich, 185 pPara->pDelSet, pPara->bInclRefToxMark ); 186 } 187 return sal_True; 188 } 189 190 sal_Bool lcl_RstAttr( const SwNodePtr& rpNd, void* pArgs ) 191 { 192 const ParaRstFmt* pPara = (ParaRstFmt*) pArgs; 193 SwCntntNode* pNode = (SwCntntNode*) rpNd->GetCntntNode(); 194 if( pNode && pNode->HasSwAttrSet() ) 195 { 196 const sal_Bool bLocked = pNode->IsModifyLocked(); 197 pNode->LockModify(); 198 199 SwDoc* pDoc = pNode->GetDoc(); 200 201 SfxItemSet aSavedAttrsSet( 202 pDoc->GetAttrPool(), 203 RES_PAGEDESC, RES_BREAK, 204 RES_PARATR_NUMRULE, RES_PARATR_NUMRULE, 205 RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1, 206 0 ); 207 const SfxItemSet* pAttrSetOfNode = pNode->GetpSwAttrSet(); 208 209 SvUShorts aClearWhichIds; 210 // restoring all paragraph list attributes 211 { 212 SfxItemSet aListAttrSet( pDoc->GetAttrPool(), 213 RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1, 214 0 ); 215 aListAttrSet.Set( *pAttrSetOfNode ); 216 if ( aListAttrSet.Count() ) 217 { 218 aSavedAttrsSet.Put( aListAttrSet ); 219 SfxItemIter aIter( aListAttrSet ); 220 const SfxPoolItem* pItem = aIter.GetCurItem(); 221 while( pItem ) 222 { 223 aClearWhichIds.Insert( pItem->Which(), aClearWhichIds.Count() ); 224 pItem = aIter.NextItem(); 225 } 226 } 227 } 228 229 const SfxPoolItem* pItem; 230 sal_uInt16 __READONLY_DATA aSavIds[3] = 231 { RES_PAGEDESC, RES_BREAK, RES_PARATR_NUMRULE }; 232 for ( sal_uInt16 n = 0; n < 3; ++n ) 233 { 234 if ( SFX_ITEM_SET == pAttrSetOfNode->GetItemState( aSavIds[n], sal_False, &pItem ) ) 235 { 236 bool bSave = false; 237 switch (aSavIds[n]) 238 { 239 case RES_PAGEDESC: 240 bSave = 0 != ( (SwFmtPageDesc*) pItem )->GetPageDesc(); 241 break; 242 case RES_BREAK: 243 bSave = SVX_BREAK_NONE != ( (SvxFmtBreakItem*) pItem )->GetBreak(); 244 break; 245 case RES_PARATR_NUMRULE: 246 bSave = 0 != ( (SwNumRuleItem*) pItem )->GetValue().Len(); 247 break; 248 } 249 if ( bSave ) 250 { 251 aSavedAttrsSet.Put( *pItem ); 252 aClearWhichIds.Insert( aSavIds[n], aClearWhichIds.Count() ); 253 } 254 } 255 } 256 257 // do not clear items directly from item set and only clear to be kept 258 // attributes, if no deletion item set is found. 259 const bool bKeepAttributes = 260 !pPara || !pPara->pDelSet || pPara->pDelSet->Count() == 0; 261 if ( bKeepAttributes ) 262 { 263 pNode->ResetAttr( aClearWhichIds ); 264 } 265 266 if( !bLocked ) 267 pNode->UnlockModify(); 268 269 if ( pPara ) 270 { 271 SwRegHistory aRegH( pNode, *pNode, pPara->pHistory ); 272 273 if ( pPara->pDelSet && pPara->pDelSet->Count() ) 274 { 275 ASSERT( !bKeepAttributes, 276 "<lcl_RstAttr(..)> - certain attributes are kept, but not needed. -> please inform OD" ); 277 SfxItemIter aIter( *pPara->pDelSet ); 278 pItem = aIter.FirstItem(); 279 while ( sal_True ) 280 { 281 if ( ( pItem->Which() != RES_PAGEDESC && 282 pItem->Which() != RES_BREAK && 283 pItem->Which() != RES_PARATR_NUMRULE ) || 284 ( aSavedAttrsSet.GetItemState( pItem->Which(), sal_False ) != SFX_ITEM_SET ) ) 285 { 286 pNode->ResetAttr( pItem->Which() ); 287 } 288 if ( aIter.IsAtEnd() ) 289 break; 290 pItem = aIter.NextItem(); 291 } 292 } 293 else if ( pPara->bResetAll ) 294 pNode->ResetAllAttr(); 295 else 296 pNode->ResetAttr( RES_PARATR_BEGIN, POOLATTR_END - 1 ); 297 } 298 else 299 pNode->ResetAllAttr(); 300 301 // only restore saved attributes, if needed 302 if ( bKeepAttributes && aSavedAttrsSet.Count() ) 303 { 304 pNode->LockModify(); 305 306 pNode->SetAttr( aSavedAttrsSet ); 307 308 if ( !bLocked ) 309 pNode->UnlockModify(); 310 } 311 } 312 return sal_True; 313 } 314 315 316 void SwDoc::RstTxtAttrs(const SwPaM &rRg, sal_Bool bInclRefToxMark ) 317 { 318 SwHistory* pHst = 0; 319 SwDataChanged aTmp( rRg, 0 ); 320 if (GetIDocumentUndoRedo().DoesUndo()) 321 { 322 SwUndoResetAttr* pUndo = new SwUndoResetAttr( rRg, RES_CHRFMT ); 323 pHst = &pUndo->GetHistory(); 324 GetIDocumentUndoRedo().AppendUndo(pUndo); 325 } 326 const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End(); 327 ParaRstFmt aPara( pStt, pEnd, pHst ); 328 aPara.bInclRefToxMark = ( bInclRefToxMark == sal_True ); 329 GetNodes().ForEach( pStt->nNode.GetIndex(), pEnd->nNode.GetIndex()+1, 330 lcl_RstTxtAttr, &aPara ); 331 SetModified(); 332 } 333 334 void SwDoc::ResetAttrs( const SwPaM &rRg, 335 sal_Bool bTxtAttr, 336 const SvUShortsSort* pAttrs, 337 // --> OD 2008-11-28 #b96644# 338 const bool bSendDataChangedEvents ) 339 // <-- 340 { 341 SwPaM* pPam = (SwPaM*)&rRg; 342 if( !bTxtAttr && pAttrs && pAttrs->Count() && 343 RES_TXTATR_END > (*pAttrs)[ 0 ] ) 344 bTxtAttr = sal_True; 345 346 if( !rRg.HasMark() ) 347 { 348 SwTxtNode* pTxtNd = rRg.GetPoint()->nNode.GetNode().GetTxtNode(); 349 if( !pTxtNd ) 350 return ; 351 352 pPam = new SwPaM( *rRg.GetPoint() ); 353 354 SwIndex& rSt = pPam->GetPoint()->nContent; 355 sal_uInt16 nMkPos, nPtPos = rSt.GetIndex(); 356 357 // JP 22.08.96: Sonderfall: steht der Crsr in einem URL-Attribut 358 // dann wird dessen Bereich genommen 359 SwTxtAttr const*const pURLAttr( 360 pTxtNd->GetTxtAttrAt(rSt.GetIndex(), RES_TXTATR_INETFMT)); 361 if (pURLAttr && pURLAttr->GetINetFmt().GetValue().Len()) 362 { 363 nMkPos = *pURLAttr->GetStart(); 364 nPtPos = *pURLAttr->End(); 365 } 366 else 367 { 368 Boundary aBndry; 369 if( pBreakIt->GetBreakIter().is() ) 370 aBndry = pBreakIt->GetBreakIter()->getWordBoundary( 371 pTxtNd->GetTxt(), nPtPos, 372 pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), 373 WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/, 374 sal_True ); 375 376 if( aBndry.startPos < nPtPos && nPtPos < aBndry.endPos ) 377 { 378 nMkPos = (xub_StrLen)aBndry.startPos; 379 nPtPos = (xub_StrLen)aBndry.endPos; 380 } 381 else 382 { 383 nPtPos = nMkPos = rSt.GetIndex(); 384 if( bTxtAttr ) 385 pTxtNd->DontExpandFmt( rSt, sal_True ); 386 } 387 } 388 389 rSt = nMkPos; 390 pPam->SetMark(); 391 pPam->GetPoint()->nContent = nPtPos; 392 } 393 394 // --> OD 2008-11-28 #i96644# 395 // SwDataChanged aTmp( *pPam, 0 ); 396 std::auto_ptr< SwDataChanged > pDataChanged; 397 if ( bSendDataChangedEvents ) 398 { 399 pDataChanged.reset( new SwDataChanged( *pPam, 0 ) ); 400 } 401 // <-- 402 SwHistory* pHst = 0; 403 if (GetIDocumentUndoRedo().DoesUndo()) 404 { 405 SwUndoResetAttr* pUndo = new SwUndoResetAttr( rRg, 406 static_cast<sal_uInt16>(bTxtAttr ? RES_CONDTXTFMTCOLL : RES_TXTFMTCOLL )); 407 if( pAttrs && pAttrs->Count() ) 408 { 409 pUndo->SetAttrs( *pAttrs ); 410 } 411 pHst = &pUndo->GetHistory(); 412 GetIDocumentUndoRedo().AppendUndo(pUndo); 413 } 414 415 const SwPosition *pStt = pPam->Start(), *pEnd = pPam->End(); 416 ParaRstFmt aPara( pStt, pEnd, pHst ); 417 418 // mst: not including META here; it seems attrs with CH_TXTATR are omitted 419 sal_uInt16 __FAR_DATA aResetableSetRange[] = { 420 RES_FRMATR_BEGIN, RES_FRMATR_END-1, 421 RES_CHRATR_BEGIN, RES_CHRATR_END-1, 422 RES_PARATR_BEGIN, RES_PARATR_END-1, 423 // --> OD 2008-02-25 #refactorlists# 424 RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1, 425 // <-- 426 RES_TXTATR_INETFMT, RES_TXTATR_INETFMT, 427 RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT, 428 RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY, 429 RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER, 430 RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, 431 0 432 }; 433 434 SfxItemSet aDelSet( GetAttrPool(), aResetableSetRange ); 435 if( pAttrs && pAttrs->Count() ) 436 { 437 for( sal_uInt16 n = pAttrs->Count(); n; ) 438 if( POOLATTR_END > (*pAttrs)[ --n ] ) 439 aDelSet.Put( *GetDfltAttr( (*pAttrs)[ n ] )); 440 441 if( aDelSet.Count() ) 442 aPara.pDelSet = &aDelSet; 443 } 444 445 sal_Bool bAdd = sal_True; 446 SwNodeIndex aTmpStt( pStt->nNode ); 447 SwNodeIndex aTmpEnd( pEnd->nNode ); 448 if( pStt->nContent.GetIndex() ) // nur ein Teil 449 { 450 // dann spaeter aufsetzen und alle CharFmtAttr -> TxtFmtAttr 451 SwTxtNode* pTNd = aTmpStt.GetNode().GetTxtNode(); 452 if( pTNd && pTNd->HasSwAttrSet() && pTNd->GetpSwAttrSet()->Count() ) 453 { 454 if (pHst) 455 { 456 SwRegHistory history(pTNd, *pTNd, pHst); 457 pTNd->FmtToTxtAttr(pTNd); 458 } 459 else 460 { 461 pTNd->FmtToTxtAttr(pTNd); 462 } 463 } 464 465 aTmpStt++; 466 } 467 if( pEnd->nContent.GetIndex() == pEnd->nNode.GetNode().GetCntntNode()->Len() ) 468 // dann spaeter aufsetzen und alle CharFmtAttr -> TxtFmtAttr 469 aTmpEnd++, bAdd = sal_False; 470 else if( pStt->nNode != pEnd->nNode || !pStt->nContent.GetIndex() ) 471 { 472 SwTxtNode* pTNd = aTmpEnd.GetNode().GetTxtNode(); 473 if( pTNd && pTNd->HasSwAttrSet() && pTNd->GetpSwAttrSet()->Count() ) 474 { 475 if (pHst) 476 { 477 SwRegHistory history(pTNd, *pTNd, pHst); 478 pTNd->FmtToTxtAttr(pTNd); 479 } 480 else 481 { 482 pTNd->FmtToTxtAttr(pTNd); 483 } 484 } 485 } 486 487 if( aTmpStt < aTmpEnd ) 488 GetNodes().ForEach( pStt->nNode, aTmpEnd, lcl_RstAttr, &aPara ); 489 else if( !rRg.HasMark() ) 490 { 491 aPara.bResetAll = false ; 492 ::lcl_RstAttr( &pStt->nNode.GetNode(), &aPara ); 493 aPara.bResetAll = true ; 494 } 495 496 if( bTxtAttr ) 497 { 498 if( bAdd ) 499 aTmpEnd++; 500 GetNodes().ForEach( pStt->nNode, aTmpEnd, lcl_RstTxtAttr, &aPara ); 501 } 502 503 if( pPam != &rRg ) 504 delete pPam; 505 506 SetModified(); 507 } 508 509 #define DELETECHARSETS if ( bDelete ) { delete pCharSet; delete pOtherSet; } 510 511 // Einfuegen der Hints nach Inhaltsformen; 512 // wird in SwDoc::Insert(..., SwFmtHint &rHt) benutzt 513 514 static bool lcl_InsAttr( 515 SwDoc *const pDoc, 516 const SwPaM &rRg, 517 const SfxItemSet& rChgSet, 518 const SetAttrMode nFlags, 519 SwUndoAttr *const pUndo, 520 //Modify here for #119405, by easyfan, 2012-05-24 521 const bool bExpandCharToPara=false) 522 //End of modification, by easyfan 523 { 524 // teil die Sets auf (fuer Selektion in Nodes) 525 const SfxItemSet* pCharSet = 0; 526 const SfxItemSet* pOtherSet = 0; 527 bool bDelete = false; 528 bool bCharAttr = false; 529 bool bOtherAttr = false; 530 531 // Check, if we can work with rChgSet or if we have to create additional SfxItemSets 532 if ( 1 == rChgSet.Count() ) 533 { 534 SfxItemIter aIter( rChgSet ); 535 const SfxPoolItem* pItem = aIter.FirstItem(); 536 537 if (!IsInvalidItem(pItem)) 538 { 539 const sal_uInt16 nWhich = pItem->Which(); 540 541 if ( isCHRATR(nWhich) || 542 (RES_TXTATR_CHARFMT == nWhich) || 543 (RES_TXTATR_INETFMT == nWhich) || 544 (RES_TXTATR_AUTOFMT == nWhich) || 545 (RES_TXTATR_UNKNOWN_CONTAINER == nWhich) ) 546 { 547 pCharSet = &rChgSet; 548 bCharAttr = true; 549 } 550 551 if ( isPARATR(nWhich) 552 || isPARATR_LIST(nWhich) 553 || isFRMATR(nWhich) 554 || isGRFATR(nWhich) 555 || isUNKNOWNATR(nWhich) ) 556 { 557 pOtherSet = &rChgSet; 558 bOtherAttr = true; 559 } 560 } 561 } 562 563 // Build new itemset if either 564 // - rChgSet.Count() > 1 or 565 // - The attribute in rChgSet does not belong to one of the above categories 566 if ( !bCharAttr && !bOtherAttr ) 567 { 568 SfxItemSet* pTmpCharItemSet = new SfxItemSet( pDoc->GetAttrPool(), 569 RES_CHRATR_BEGIN, RES_CHRATR_END-1, 570 RES_TXTATR_AUTOFMT, RES_TXTATR_AUTOFMT, 571 RES_TXTATR_INETFMT, RES_TXTATR_INETFMT, 572 RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT, 573 RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER, 574 0 ); 575 576 SfxItemSet* pTmpOtherItemSet = new SfxItemSet( pDoc->GetAttrPool(), 577 RES_PARATR_BEGIN, RES_PARATR_END-1, 578 RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1, 579 RES_FRMATR_BEGIN, RES_FRMATR_END-1, 580 RES_GRFATR_BEGIN, RES_GRFATR_END-1, 581 RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, 582 0 ); 583 584 pTmpCharItemSet->Put( rChgSet ); 585 pTmpOtherItemSet->Put( rChgSet ); 586 587 pCharSet = pTmpCharItemSet; 588 pOtherSet = pTmpOtherItemSet; 589 590 bDelete = true; 591 } 592 593 SwHistory* pHistory = pUndo ? &pUndo->GetHistory() : 0; 594 bool bRet = false; 595 const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End(); 596 SwCntntNode* pNode = pStt->nNode.GetNode().GetCntntNode(); 597 598 if( pNode && pNode->IsTxtNode() ) 599 { 600 // -> #i27615# 601 if (rRg.IsInFrontOfLabel()) 602 { 603 SwTxtNode * pTxtNd = pNode->GetTxtNode(); 604 SwNumRule * pNumRule = pTxtNd->GetNumRule(); 605 606 if ( !pNumRule ) 607 { 608 ASSERT( false, 609 "<InsAttr(..)> - PaM in front of label, but text node has no numbering rule set. This is a serious defect, please inform OD." ); 610 DELETECHARSETS 611 return false; 612 } 613 614 SwNumFmt aNumFmt = pNumRule->Get(static_cast<sal_uInt16>(pTxtNd->GetActualListLevel())); 615 SwCharFmt * pCharFmt = 616 pDoc->FindCharFmtByName(aNumFmt.GetCharFmtName()); 617 618 if (pCharFmt) 619 { 620 if (pHistory) 621 pHistory->Add(pCharFmt->GetAttrSet(), *pCharFmt); 622 623 if ( pCharSet ) 624 pCharFmt->SetFmtAttr(*pCharSet); 625 } 626 627 DELETECHARSETS 628 return true; 629 } 630 631 const SwIndex& rSt = pStt->nContent; 632 633 // Attribute ohne Ende haben keinen Bereich 634 if ( !bCharAttr && !bOtherAttr ) 635 { 636 SfxItemSet aTxtSet( pDoc->GetAttrPool(), 637 RES_TXTATR_NOEND_BEGIN, RES_TXTATR_NOEND_END-1 ); 638 aTxtSet.Put( rChgSet ); 639 if( aTxtSet.Count() ) 640 { 641 SwRegHistory history( pNode, *pNode, pHistory ); 642 bRet = history.InsertItems( 643 aTxtSet, rSt.GetIndex(), rSt.GetIndex(), nFlags ) || bRet; 644 645 if (bRet && (pDoc->IsRedlineOn() || (!pDoc->IsIgnoreRedline() 646 && pDoc->GetRedlineTbl().Count()))) 647 { 648 SwPaM aPam( pStt->nNode, pStt->nContent.GetIndex()-1, 649 pStt->nNode, pStt->nContent.GetIndex() ); 650 651 if( pUndo ) 652 pUndo->SaveRedlineData( aPam, sal_True ); 653 654 if( pDoc->IsRedlineOn() ) 655 pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true); 656 else 657 pDoc->SplitRedline( aPam ); 658 } 659 } 660 } 661 662 // TextAttribute mit Ende expandieren nie ihren Bereich 663 if ( !bCharAttr && !bOtherAttr ) 664 { 665 // CharFmt wird gesondert behandelt !!! 666 // JP 22.08.96: URL-Attribute auch!! 667 // TEST_TEMP ToDo: AutoFmt! 668 SfxItemSet aTxtSet( pDoc->GetAttrPool(), 669 RES_TXTATR_REFMARK, RES_TXTATR_TOXMARK, 670 RES_TXTATR_META, RES_TXTATR_METAFIELD, 671 RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY, 672 RES_TXTATR_INPUTFIELD, RES_TXTATR_INPUTFIELD, 673 0 ); 674 675 aTxtSet.Put( rChgSet ); 676 if( aTxtSet.Count() ) 677 { 678 sal_uInt16 nInsCnt = rSt.GetIndex(); 679 sal_uInt16 nEnd = pStt->nNode == pEnd->nNode 680 ? pEnd->nContent.GetIndex() 681 : pNode->Len(); 682 SwRegHistory history( pNode, *pNode, pHistory ); 683 bRet = history.InsertItems( aTxtSet, nInsCnt, nEnd, nFlags ) 684 || bRet; 685 686 if (bRet && (pDoc->IsRedlineOn() || (!pDoc->IsIgnoreRedline() 687 && pDoc->GetRedlineTbl().Count()))) 688 { 689 // wurde Text-Inhalt eingefuegt? (RefMark/TOXMarks ohne Ende) 690 sal_Bool bTxtIns = nInsCnt != rSt.GetIndex(); 691 // wurde Inhalt eingefuegt oder ueber die Selektion gesetzt? 692 SwPaM aPam( pStt->nNode, bTxtIns ? nInsCnt + 1 : nEnd, 693 pStt->nNode, nInsCnt ); 694 if( pUndo ) 695 pUndo->SaveRedlineData( aPam, bTxtIns ); 696 697 if( pDoc->IsRedlineOn() ) 698 pDoc->AppendRedline( 699 new SwRedline( 700 bTxtIns ? nsRedlineType_t::REDLINE_INSERT : nsRedlineType_t::REDLINE_FORMAT, aPam ), 701 true); 702 else if( bTxtIns ) 703 pDoc->SplitRedline( aPam ); 704 } 705 } 706 } 707 } 708 709 // bei PageDesc's, die am Node gesetzt werden, muss immer das 710 // Auto-Flag gesetzt werden!! 711 if( pOtherSet && pOtherSet->Count() ) 712 { 713 SwTableNode* pTblNd; 714 const SwFmtPageDesc* pDesc; 715 if( SFX_ITEM_SET == pOtherSet->GetItemState( RES_PAGEDESC, 716 sal_False, (const SfxPoolItem**)&pDesc )) 717 { 718 if( pNode ) 719 { 720 // Auto-Flag setzen, nur in Vorlagen ist ohne Auto ! 721 SwFmtPageDesc aNew( *pDesc ); 722 // Bug 38479: AutoFlag wird jetzt in der WrtShell gesetzt 723 // aNew.SetAuto(); 724 725 // Tabellen kennen jetzt auch Umbrueche 726 if( 0 == (nFlags & nsSetAttrMode::SETATTR_APICALL) && 727 0 != ( pTblNd = pNode->FindTableNode() ) ) 728 { 729 SwTableNode* pCurTblNd = pTblNd; 730 while ( 0 != ( pCurTblNd = pCurTblNd->StartOfSectionNode()->FindTableNode() ) ) 731 pTblNd = pCurTblNd; 732 733 // dann am Tabellen Format setzen 734 SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt(); 735 SwRegHistory aRegH( pFmt, *pTblNd, pHistory ); 736 pFmt->SetFmtAttr( aNew ); 737 bRet = true; 738 } 739 else 740 { 741 SwRegHistory aRegH( pNode, *pNode, pHistory ); 742 bRet = pNode->SetAttr( aNew ) || bRet; 743 } 744 } 745 746 // bOtherAttr = true means that pOtherSet == rChgSet. In this case 747 // we know, that there is only one attribute in pOtherSet. We cannot 748 // perform the following operations, instead we return: 749 if ( bOtherAttr ) 750 return bRet; 751 752 const_cast<SfxItemSet*>(pOtherSet)->ClearItem( RES_PAGEDESC ); 753 if( !pOtherSet->Count() ) 754 { 755 DELETECHARSETS 756 return bRet; 757 } 758 } 759 760 // Tabellen kennen jetzt auch Umbrueche 761 const SvxFmtBreakItem* pBreak; 762 if( pNode && 0 == (nFlags & nsSetAttrMode::SETATTR_APICALL) && 763 0 != (pTblNd = pNode->FindTableNode() ) && 764 SFX_ITEM_SET == pOtherSet->GetItemState( RES_BREAK, 765 sal_False, (const SfxPoolItem**)&pBreak ) ) 766 { 767 SwTableNode* pCurTblNd = pTblNd; 768 while ( 0 != ( pCurTblNd = pCurTblNd->StartOfSectionNode()->FindTableNode() ) ) 769 pTblNd = pCurTblNd; 770 771 // dann am Tabellen Format setzen 772 SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt(); 773 SwRegHistory aRegH( pFmt, *pTblNd, pHistory ); 774 pFmt->SetFmtAttr( *pBreak ); 775 bRet = true; 776 777 // bOtherAttr = true means that pOtherSet == rChgSet. In this case 778 // we know, that there is only one attribute in pOtherSet. We cannot 779 // perform the following operations, instead we return: 780 if ( bOtherAttr ) 781 return bRet; 782 783 const_cast<SfxItemSet*>(pOtherSet)->ClearItem( RES_BREAK ); 784 if( !pOtherSet->Count() ) 785 { 786 DELETECHARSETS 787 return bRet; 788 } 789 } 790 791 { 792 // wenns eine PoolNumRule ist, diese ggfs. anlegen 793 const SwNumRuleItem* pRule; 794 sal_uInt16 nPoolId; 795 if( SFX_ITEM_SET == pOtherSet->GetItemState( RES_PARATR_NUMRULE, 796 sal_False, (const SfxPoolItem**)&pRule ) && 797 !pDoc->FindNumRulePtr( pRule->GetValue() ) && 798 USHRT_MAX != (nPoolId = SwStyleNameMapper::GetPoolIdFromUIName ( pRule->GetValue(), 799 nsSwGetPoolIdFromName::GET_POOLID_NUMRULE )) ) 800 pDoc->GetNumRuleFromPool( nPoolId ); 801 } 802 803 } 804 805 if( !rRg.HasMark() ) // kein Bereich 806 { 807 if( !pNode ) 808 { 809 DELETECHARSETS 810 return bRet; 811 } 812 813 if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() ) 814 { 815 SwTxtNode* pTxtNd = static_cast<SwTxtNode*>(pNode); 816 const SwIndex& rSt = pStt->nContent; 817 sal_uInt16 nMkPos, nPtPos = rSt.GetIndex(); 818 const String& rStr = pTxtNd->GetTxt(); 819 820 // JP 22.08.96: Sonderfall: steht der Crsr in einem URL-Attribut 821 // dann wird dessen Bereich genommen 822 SwTxtAttr const*const pURLAttr( 823 pTxtNd->GetTxtAttrAt(rSt.GetIndex(), RES_TXTATR_INETFMT)); 824 if (pURLAttr && pURLAttr->GetINetFmt().GetValue().Len()) 825 { 826 nMkPos = *pURLAttr->GetStart(); 827 nPtPos = *pURLAttr->End(); 828 } 829 else 830 { 831 Boundary aBndry; 832 if( pBreakIt->GetBreakIter().is() ) 833 aBndry = pBreakIt->GetBreakIter()->getWordBoundary( 834 pTxtNd->GetTxt(), nPtPos, 835 pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), 836 WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/, 837 sal_True ); 838 839 if( aBndry.startPos < nPtPos && nPtPos < aBndry.endPos ) 840 { 841 nMkPos = (xub_StrLen)aBndry.startPos; 842 nPtPos = (xub_StrLen)aBndry.endPos; 843 } 844 else 845 nPtPos = nMkPos = rSt.GetIndex(); 846 } 847 848 // erstmal die zu ueberschreibenden Attribute aus dem 849 // SwpHintsArray entfernen, wenn die Selektion den gesamten 850 // Absatz umspannt. (Diese Attribute werden als FormatAttr. 851 // eingefuegt und verdraengen nie die TextAttr.!) 852 if( !(nFlags & nsSetAttrMode::SETATTR_DONTREPLACE ) && 853 pTxtNd->HasHints() && !nMkPos && nPtPos == rStr.Len() ) 854 { 855 SwIndex aSt( pTxtNd ); 856 if( pHistory ) 857 { 858 // fuers Undo alle Attribute sichern 859 SwRegHistory aRHst( *pTxtNd, pHistory ); 860 pTxtNd->GetpSwpHints()->Register( &aRHst ); 861 pTxtNd->RstTxtAttr( aSt, nPtPos, 0, pCharSet ); 862 if( pTxtNd->GetpSwpHints() ) 863 pTxtNd->GetpSwpHints()->DeRegister(); 864 } 865 else 866 pTxtNd->RstTxtAttr( aSt, nPtPos, 0, pCharSet ); 867 } 868 869 // the SwRegHistory inserts the attribute into the TxtNode! 870 SwRegHistory history( pNode, *pNode, pHistory ); 871 bRet = history.InsertItems( *pCharSet, nMkPos, nPtPos, nFlags ) 872 || bRet; 873 874 if( pDoc->IsRedlineOn() ) 875 { 876 SwPaM aPam( *pNode, nMkPos, *pNode, nPtPos ); 877 878 if( pUndo ) 879 pUndo->SaveRedlineData( aPam, sal_False ); 880 pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_FORMAT, aPam ), true); 881 } 882 } 883 if( pOtherSet && pOtherSet->Count() ) 884 { 885 SwRegHistory aRegH( pNode, *pNode, pHistory ); 886 bRet = pNode->SetAttr( *pOtherSet ) || bRet; 887 } 888 889 DELETECHARSETS 890 return bRet; 891 } 892 893 if( pDoc->IsRedlineOn() && pCharSet && pCharSet->Count() ) 894 { 895 if( pUndo ) 896 pUndo->SaveRedlineData( rRg, sal_False ); 897 pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_FORMAT, rRg ), true); 898 } 899 900 /* jetzt wenn Bereich */ 901 sal_uLong nNodes = 0; 902 903 SwNodeIndex aSt( pDoc->GetNodes() ); 904 SwNodeIndex aEnd( pDoc->GetNodes() ); 905 SwIndex aCntEnd( pEnd->nContent ); 906 907 if( pNode ) 908 { 909 sal_uInt16 nLen = pNode->Len(); 910 if( pStt->nNode != pEnd->nNode ) 911 aCntEnd.Assign( pNode, nLen ); 912 913 if( pStt->nContent.GetIndex() != 0 || aCntEnd.GetIndex() != nLen ) 914 { 915 // the SwRegHistory inserts the attribute into the TxtNode! 916 if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() ) 917 { 918 SwRegHistory history( pNode, *pNode, pHistory ); 919 bRet = history.InsertItems(*pCharSet, 920 pStt->nContent.GetIndex(), aCntEnd.GetIndex(), nFlags) 921 || bRet; 922 } 923 924 if( pOtherSet && pOtherSet->Count() ) 925 { 926 SwRegHistory aRegH( pNode, *pNode, pHistory ); 927 bRet = pNode->SetAttr( *pOtherSet ) || bRet; 928 } 929 930 // lediglich Selektion in einem Node. 931 if( pStt->nNode == pEnd->nNode ) 932 { 933 //Modify here for #119405, by easyfan, 2012-05-24 934 //The data parameter flag: bExpandCharToPara, comes from the data member of SwDoc, 935 //Which is set in SW MS word Binary filter WW8ImplRreader. With this flag on, means that 936 //current setting attribute set is a character range properties set and comes from a MS word 937 //binary file, And the setting range include a paragraph end position (0X0D); 938 //More specifications, as such property inside the character range properties set recorded in 939 //MS word binary file are dealed and inserted into data model (SwDoc) one by one, so we 940 //only dealing the scenario that the char properties set with 1 item inside; 941 942 if (bExpandCharToPara && pCharSet && pCharSet->Count() ==1 ) 943 { 944 SwTxtNode* pCurrentNd = pStt->nNode.GetNode().GetTxtNode(); 945 946 if (pCurrentNd) 947 { 948 pCurrentNd->TryCharSetExpandToNum(*pCharSet); 949 950 } 951 } 952 //End of modification, by easyfan 953 DELETECHARSETS 954 return bRet; 955 } 956 ++nNodes; 957 aSt.Assign( pStt->nNode.GetNode(), +1 ); 958 } 959 else 960 aSt = pStt->nNode; 961 aCntEnd = pEnd->nContent; // aEnd wurde veraendert !! 962 } 963 else 964 aSt.Assign( pStt->nNode.GetNode(), +1 ); 965 966 // aSt zeigt jetzt auf den ersten vollen Node 967 968 /* 969 * die Selektion umfasst mehr als einen Node 970 */ 971 if( pStt->nNode < pEnd->nNode ) 972 { 973 pNode = pEnd->nNode.GetNode().GetCntntNode(); 974 if(pNode) 975 { 976 sal_uInt16 nLen = pNode->Len(); 977 if( aCntEnd.GetIndex() != nLen ) 978 { 979 // the SwRegHistory inserts the attribute into the TxtNode! 980 if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() ) 981 { 982 SwRegHistory history( pNode, *pNode, pHistory ); 983 history.InsertItems(*pCharSet, 984 0, aCntEnd.GetIndex(), nFlags); 985 } 986 987 if( pOtherSet && pOtherSet->Count() ) 988 { 989 SwRegHistory aRegH( pNode, *pNode, pHistory ); 990 pNode->SetAttr( *pOtherSet ); 991 } 992 993 ++nNodes; 994 aEnd = pEnd->nNode; 995 } 996 else 997 aEnd.Assign( pEnd->nNode.GetNode(), +1 ); 998 } 999 else 1000 aEnd = pEnd->nNode; 1001 } 1002 else 1003 aEnd.Assign( pEnd->nNode.GetNode(), +1 ); 1004 1005 // aEnd zeigt jetzt HINTER den letzten voll Node 1006 1007 /* Bearbeitung der vollstaendig selektierten Nodes. */ 1008 // alle Attribute aus dem Set zuruecksetzen !! 1009 if( pCharSet && pCharSet->Count() && !( nsSetAttrMode::SETATTR_DONTREPLACE & nFlags ) ) 1010 { 1011 1012 ParaRstFmt aPara( pStt, pEnd, pHistory, 0, pCharSet ); 1013 pDoc->GetNodes().ForEach( aSt, aEnd, lcl_RstTxtAttr, &aPara ); 1014 } 1015 1016 sal_Bool bCreateSwpHints = pCharSet && ( 1017 SFX_ITEM_SET == pCharSet->GetItemState( RES_TXTATR_CHARFMT, sal_False ) || 1018 SFX_ITEM_SET == pCharSet->GetItemState( RES_TXTATR_INETFMT, sal_False ) ); 1019 1020 for(; aSt < aEnd; aSt++ ) 1021 { 1022 pNode = aSt.GetNode().GetCntntNode(); 1023 if( !pNode ) 1024 continue; 1025 1026 SwTxtNode* pTNd = pNode->GetTxtNode(); 1027 if( pHistory ) 1028 { 1029 SwRegHistory aRegH( pNode, *pNode, pHistory ); 1030 SwpHints *pSwpHints; 1031 1032 if( pTNd && pCharSet && pCharSet->Count() ) 1033 { 1034 pSwpHints = bCreateSwpHints ? &pTNd->GetOrCreateSwpHints() 1035 : pTNd->GetpSwpHints(); 1036 if( pSwpHints ) 1037 pSwpHints->Register( &aRegH ); 1038 1039 pTNd->SetAttr( *pCharSet, 0, pTNd->GetTxt().Len(), nFlags ); 1040 if( pSwpHints ) 1041 pSwpHints->DeRegister(); 1042 } 1043 if( pOtherSet && pOtherSet->Count() ) 1044 pNode->SetAttr( *pOtherSet ); 1045 } 1046 else 1047 { 1048 if( pTNd && pCharSet && pCharSet->Count() ) 1049 pTNd->SetAttr( *pCharSet, 0, pTNd->GetTxt().Len(), nFlags ); 1050 if( pOtherSet && pOtherSet->Count() ) 1051 pNode->SetAttr( *pOtherSet ); 1052 } 1053 ++nNodes; 1054 } 1055 1056 //The data parameter flag: bExpandCharToPara, comes from the data member of SwDoc, 1057 //Which is set in SW MS word Binary filter WW8ImplRreader. With this flag on, means that 1058 //current setting attribute set is a character range properties set and comes from a MS word 1059 //binary file, And the setting range include a paragraph end position (0X0D); 1060 //More specifications, as such property inside the character range properties set recorded in 1061 //MS word binary file are dealed and inserted into data model (SwDoc) one by one, so we 1062 //only dealing the scenario that the char properties set with 1 item inside; 1063 if (bExpandCharToPara && pCharSet && pCharSet->Count() ==1) 1064 { 1065 SwPosition aStartPos (*rRg.Start()); 1066 SwPosition aEndPos (*rRg.End()); 1067 1068 if (aEndPos.nNode.GetNode().GetTxtNode() && aEndPos.nContent != aEndPos.nNode.GetNode().GetTxtNode()->Len()) 1069 aEndPos.nNode--; 1070 1071 for (;aStartPos<=aEndPos;aStartPos.nNode++) 1072 { 1073 SwTxtNode* pCurrentNd = aStartPos.nNode.GetNode().GetTxtNode(); 1074 1075 if (pCurrentNd) 1076 { 1077 pCurrentNd->TryCharSetExpandToNum(*pCharSet); 1078 1079 } 1080 1081 } 1082 } 1083 1084 DELETECHARSETS 1085 return (nNodes != 0) || bRet; 1086 } 1087 1088 bool SwDoc::InsertPoolItem( 1089 const SwPaM &rRg, 1090 const SfxPoolItem &rHt, 1091 const SetAttrMode nFlags, 1092 const bool bExpandCharToPara) 1093 { 1094 SwDataChanged aTmp( rRg, 0 ); 1095 SwUndoAttr* pUndoAttr = 0; 1096 if (GetIDocumentUndoRedo().DoesUndo()) 1097 { 1098 GetIDocumentUndoRedo().ClearRedo(); 1099 pUndoAttr = new SwUndoAttr( rRg, rHt, nFlags ); 1100 } 1101 1102 SfxItemSet aSet( GetAttrPool(), rHt.Which(), rHt.Which() ); 1103 aSet.Put( rHt ); 1104 const bool bRet = lcl_InsAttr( this, rRg, aSet, nFlags, pUndoAttr,bExpandCharToPara ); 1105 1106 if (GetIDocumentUndoRedo().DoesUndo()) 1107 { 1108 GetIDocumentUndoRedo().AppendUndo( pUndoAttr ); 1109 } 1110 1111 if( bRet ) 1112 { 1113 SetModified(); 1114 } 1115 return bRet; 1116 } 1117 1118 bool SwDoc::InsertItemSet ( const SwPaM &rRg, const SfxItemSet &rSet, 1119 const SetAttrMode nFlags ) 1120 { 1121 SwDataChanged aTmp( rRg, 0 ); 1122 SwUndoAttr* pUndoAttr = 0; 1123 if (GetIDocumentUndoRedo().DoesUndo()) 1124 { 1125 GetIDocumentUndoRedo().ClearRedo(); 1126 pUndoAttr = new SwUndoAttr( rRg, rSet, nFlags ); 1127 } 1128 1129 bool bRet = lcl_InsAttr( this, rRg, rSet, nFlags, pUndoAttr ); 1130 1131 if (GetIDocumentUndoRedo().DoesUndo()) 1132 { 1133 GetIDocumentUndoRedo().AppendUndo( pUndoAttr ); 1134 } 1135 1136 if( bRet ) 1137 SetModified(); 1138 return bRet; 1139 } 1140 1141 1142 // Setze das Attribut im angegebenen Format. Ist Undo aktiv, wird 1143 // das alte in die Undo-History aufgenommen 1144 void SwDoc::SetAttr( const SfxPoolItem& rAttr, SwFmt& rFmt ) 1145 { 1146 SfxItemSet aSet( GetAttrPool(), rAttr.Which(), rAttr.Which() ); 1147 aSet.Put( rAttr ); 1148 SetAttr( aSet, rFmt ); 1149 } 1150 1151 1152 // Setze das Attribut im angegebenen Format. Ist Undo aktiv, wird 1153 // das alte in die Undo-History aufgenommen 1154 void SwDoc::SetAttr( const SfxItemSet& rSet, SwFmt& rFmt ) 1155 { 1156 if (GetIDocumentUndoRedo().DoesUndo()) 1157 { 1158 SwUndoFmtAttrHelper aTmp( rFmt ); 1159 rFmt.SetFmtAttr( rSet ); 1160 if ( aTmp.GetUndo() ) 1161 { 1162 GetIDocumentUndoRedo().AppendUndo( aTmp.ReleaseUndo() ); 1163 } 1164 else 1165 { 1166 GetIDocumentUndoRedo().ClearRedo(); 1167 } 1168 } 1169 else 1170 { 1171 rFmt.SetFmtAttr( rSet ); 1172 } 1173 SetModified(); 1174 } 1175 1176 // --> OD 2008-02-12 #newlistlevelattrs# 1177 void SwDoc::ResetAttrAtFormat( const sal_uInt16 nWhichId, 1178 SwFmt& rChangedFormat ) 1179 { 1180 SwUndo *const pUndo = (GetIDocumentUndoRedo().DoesUndo()) 1181 ? new SwUndoFmtResetAttr( rChangedFormat, nWhichId ) 1182 : 0; 1183 1184 const sal_Bool bAttrReset = rChangedFormat.ResetFmtAttr( nWhichId ); 1185 1186 if ( bAttrReset ) 1187 { 1188 if ( pUndo ) 1189 { 1190 GetIDocumentUndoRedo().AppendUndo( pUndo ); 1191 } 1192 1193 SetModified(); 1194 } 1195 else if ( pUndo ) 1196 delete pUndo; 1197 } 1198 // <-- 1199 1200 int lcl_SetNewDefTabStops( SwTwips nOldWidth, SwTwips nNewWidth, 1201 SvxTabStopItem& rChgTabStop ) 1202 { 1203 // dann aender bei allen TabStop die default's auf den neuen Wert 1204 // !!! Achtung: hier wird immer auf dem PoolAttribut gearbeitet, 1205 // damit nicht in allen Sets die gleiche Berechnung 1206 // auf dem gleichen TabStop (gepoolt!) vorgenommen 1207 // wird. Als Modify wird ein FmtChg verschickt. 1208 1209 sal_uInt16 nOldCnt = rChgTabStop.Count(); 1210 if( !nOldCnt || nOldWidth == nNewWidth ) 1211 return sal_False; 1212 1213 // suche den Anfang der Defaults 1214 SvxTabStop* pTabs = ((SvxTabStop*)rChgTabStop.GetStart()) 1215 + (nOldCnt-1); 1216 sal_uInt16 n; 1217 1218 for( n = nOldCnt; n ; --n, --pTabs ) 1219 if( SVX_TAB_ADJUST_DEFAULT != pTabs->GetAdjustment() ) 1220 break; 1221 ++n; 1222 if( n < nOldCnt ) // die DefTabStops loeschen 1223 rChgTabStop.Remove( n, nOldCnt - n ); 1224 return sal_True; 1225 } 1226 1227 // Setze das Attribut als neues default Attribut in diesem Dokument. 1228 // Ist Undo aktiv, wird das alte in die Undo-History aufgenommen 1229 void SwDoc::SetDefault( const SfxPoolItem& rAttr ) 1230 { 1231 SfxItemSet aSet( GetAttrPool(), rAttr.Which(), rAttr.Which() ); 1232 aSet.Put( rAttr ); 1233 SetDefault( aSet ); 1234 } 1235 1236 void SwDoc::SetDefault( const SfxItemSet& rSet ) 1237 { 1238 if( !rSet.Count() ) 1239 return; 1240 1241 SwModify aCallMod( 0 ); 1242 SwAttrSet aOld( GetAttrPool(), rSet.GetRanges() ), 1243 aNew( GetAttrPool(), rSet.GetRanges() ); 1244 SfxItemIter aIter( rSet ); 1245 sal_uInt16 nWhich; 1246 const SfxPoolItem* pItem = aIter.GetCurItem(); 1247 SfxItemPool* pSdrPool = GetAttrPool().GetSecondaryPool(); 1248 while( sal_True ) 1249 { 1250 sal_Bool bCheckSdrDflt = sal_False; 1251 nWhich = pItem->Which(); 1252 aOld.Put( GetAttrPool().GetDefaultItem( nWhich ) ); 1253 GetAttrPool().SetPoolDefaultItem( *pItem ); 1254 aNew.Put( GetAttrPool().GetDefaultItem( nWhich ) ); 1255 1256 if (isCHRATR(nWhich) || isTXTATR(nWhich)) 1257 { 1258 aCallMod.Add( pDfltTxtFmtColl ); 1259 aCallMod.Add( pDfltCharFmt ); 1260 bCheckSdrDflt = 0 != pSdrPool; 1261 } 1262 else if ( isPARATR(nWhich) || 1263 // --> OD 2008-02-25 #refactorlists# 1264 isPARATR_LIST(nWhich) ) 1265 // <-- 1266 { 1267 aCallMod.Add( pDfltTxtFmtColl ); 1268 bCheckSdrDflt = 0 != pSdrPool; 1269 } 1270 else if (isGRFATR(nWhich)) 1271 { 1272 aCallMod.Add( pDfltGrfFmtColl ); 1273 } 1274 else if (isFRMATR(nWhich)) 1275 { 1276 aCallMod.Add( pDfltGrfFmtColl ); 1277 aCallMod.Add( pDfltTxtFmtColl ); 1278 aCallMod.Add( pDfltFrmFmt ); 1279 } 1280 else if (isBOXATR(nWhich)) 1281 { 1282 aCallMod.Add( pDfltFrmFmt ); 1283 } 1284 1285 // copy also the defaults 1286 if( bCheckSdrDflt ) 1287 { 1288 sal_uInt16 nEdtWhich, nSlotId; 1289 if( 0 != (nSlotId = GetAttrPool().GetSlotId( nWhich ) ) && 1290 nSlotId != nWhich && 1291 0 != (nEdtWhich = pSdrPool->GetWhich( nSlotId )) && 1292 nSlotId != nEdtWhich ) 1293 { 1294 SfxPoolItem* pCpy = pItem->Clone(); 1295 pCpy->SetWhich( nEdtWhich ); 1296 pSdrPool->SetPoolDefaultItem( *pCpy ); 1297 delete pCpy; 1298 } 1299 } 1300 1301 if( aIter.IsAtEnd() ) 1302 break; 1303 pItem = aIter.NextItem(); 1304 } 1305 1306 if( aNew.Count() && aCallMod.GetDepends() ) 1307 { 1308 if (GetIDocumentUndoRedo().DoesUndo()) 1309 { 1310 GetIDocumentUndoRedo().AppendUndo( new SwUndoDefaultAttr( aOld ) ); 1311 } 1312 1313 const SfxPoolItem* pTmpItem; 1314 if( ( SFX_ITEM_SET == 1315 aNew.GetItemState( RES_PARATR_TABSTOP, sal_False, &pTmpItem ) ) && 1316 ((SvxTabStopItem*)pTmpItem)->Count() ) 1317 { 1318 // TabStop-Aenderungen behandeln wir erstmal anders: 1319 // dann aender bei allen TabStop die dafault's auf den neuen Wert 1320 // !!! Achtung: hier wird immer auf dem PoolAttribut gearbeitet, 1321 // damit nicht in allen Sets die gleiche Berechnung 1322 // auf dem gleichen TabStop (gepoolt!) vorgenommen 1323 // wird. Als Modify wird ein FmtChg verschickt. 1324 SwTwips nNewWidth = (*(SvxTabStopItem*)pTmpItem)[ 0 ].GetTabPos(), 1325 nOldWidth = ((SvxTabStopItem&)aOld.Get(RES_PARATR_TABSTOP))[ 0 ].GetTabPos(); 1326 1327 int bChg = sal_False; 1328 sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_PARATR_TABSTOP ); 1329 for( sal_uInt32 n = 0; n < nMaxItems; ++n ) 1330 if( 0 != (pTmpItem = GetAttrPool().GetItem2( RES_PARATR_TABSTOP, n ) )) 1331 bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth, 1332 *(SvxTabStopItem*)pTmpItem ); 1333 1334 aNew.ClearItem( RES_PARATR_TABSTOP ); 1335 aOld.ClearItem( RES_PARATR_TABSTOP ); 1336 if( bChg ) 1337 { 1338 SwFmtChg aChgFmt( pDfltCharFmt ); 1339 // dann sage mal den Frames bescheid 1340 aCallMod.ModifyNotification( &aChgFmt, &aChgFmt ); 1341 } 1342 } 1343 } 1344 1345 if( aNew.Count() && aCallMod.GetDepends() ) 1346 { 1347 SwAttrSetChg aChgOld( aOld, aOld ); 1348 SwAttrSetChg aChgNew( aNew, aNew ); 1349 aCallMod.ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt 1350 } 1351 1352 // und die default-Formate wieder beim Object austragen 1353 SwClient* pDep; 1354 while( 0 != ( pDep = (SwClient*)aCallMod.GetDepends()) ) 1355 aCallMod.Remove( pDep ); 1356 1357 SetModified(); 1358 } 1359 1360 // Erfrage das Default Attribut in diesem Dokument. 1361 const SfxPoolItem& SwDoc::GetDefault( sal_uInt16 nFmtHint ) const 1362 { 1363 return GetAttrPool().GetDefaultItem( nFmtHint ); 1364 } 1365 1366 /* 1367 * Loeschen der Formate 1368 */ 1369 void SwDoc::DelCharFmt(sal_uInt16 nFmt, sal_Bool bBroadcast) 1370 { 1371 SwCharFmt * pDel = (*pCharFmtTbl)[nFmt]; 1372 1373 if (bBroadcast) 1374 BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_CHAR, 1375 SFX_STYLESHEET_ERASED); 1376 1377 if (GetIDocumentUndoRedo().DoesUndo()) 1378 { 1379 SwUndo * pUndo = 1380 new SwUndoCharFmtDelete(pDel, this); 1381 1382 GetIDocumentUndoRedo().AppendUndo(pUndo); 1383 } 1384 1385 pCharFmtTbl->DeleteAndDestroy(nFmt); 1386 1387 SetModified(); 1388 } 1389 1390 void SwDoc::DelCharFmt( SwCharFmt *pFmt, sal_Bool bBroadcast ) 1391 { 1392 sal_uInt16 nFmt = pCharFmtTbl->GetPos( pFmt ); 1393 ASSERT( USHRT_MAX != nFmt, "Fmt not found," ); 1394 1395 DelCharFmt( nFmt, bBroadcast ); 1396 } 1397 1398 void SwDoc::DelFrmFmt( SwFrmFmt *pFmt, sal_Bool bBroadcast ) 1399 { 1400 if( pFmt->ISA( SwTableBoxFmt ) || pFmt->ISA( SwTableLineFmt )) 1401 { 1402 ASSERT( !this, "Format steht nicht mehr im DocArray, " 1403 "kann per delete geloescht werden" ); 1404 delete pFmt; 1405 } 1406 else 1407 { 1408 1409 //Das Format muss in einem der beiden Arrays stehen, in welchem 1410 //werden wir schon merken. 1411 sal_uInt16 nPos; 1412 if ( USHRT_MAX != ( nPos = pFrmFmtTbl->GetPos( pFmt )) ) 1413 { 1414 if (bBroadcast) 1415 BroadcastStyleOperation(pFmt->GetName(), 1416 SFX_STYLE_FAMILY_FRAME, 1417 SFX_STYLESHEET_ERASED); 1418 1419 if (GetIDocumentUndoRedo().DoesUndo()) 1420 { 1421 SwUndo * pUndo = new SwUndoFrmFmtDelete(pFmt, this); 1422 1423 GetIDocumentUndoRedo().AppendUndo(pUndo); 1424 } 1425 1426 pFrmFmtTbl->DeleteAndDestroy( nPos ); 1427 } 1428 else 1429 { 1430 nPos = GetSpzFrmFmts()->GetPos( pFmt ); 1431 ASSERT( nPos != USHRT_MAX, "FrmFmt not found." ); 1432 if( USHRT_MAX != nPos ) 1433 GetSpzFrmFmts()->DeleteAndDestroy( nPos ); 1434 } 1435 } 1436 } 1437 1438 void SwDoc::DelTblFrmFmt( SwTableFmt *pFmt ) 1439 { 1440 sal_uInt16 nPos = pTblFrmFmtTbl->GetPos( pFmt ); 1441 ASSERT( USHRT_MAX != nPos, "Fmt not found," ); 1442 pTblFrmFmtTbl->DeleteAndDestroy( nPos ); 1443 } 1444 1445 /* 1446 * Erzeugen der Formate 1447 */ 1448 SwFlyFrmFmt *SwDoc::MakeFlyFrmFmt( const String &rFmtName, 1449 SwFrmFmt *pDerivedFrom ) 1450 { 1451 SwFlyFrmFmt *pFmt = new SwFlyFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom ); 1452 GetSpzFrmFmts()->Insert(pFmt, GetSpzFrmFmts()->Count()); 1453 SetModified(); 1454 return pFmt; 1455 } 1456 1457 SwDrawFrmFmt *SwDoc::MakeDrawFrmFmt( const String &rFmtName, 1458 SwFrmFmt *pDerivedFrom ) 1459 { 1460 SwDrawFrmFmt *pFmt = new SwDrawFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom); 1461 GetSpzFrmFmts()->Insert(pFmt,GetSpzFrmFmts()->Count()); 1462 SetModified(); 1463 return pFmt; 1464 } 1465 1466 1467 sal_uInt16 SwDoc::GetTblFrmFmtCount(sal_Bool bUsed) const 1468 { 1469 sal_uInt16 nCount = pTblFrmFmtTbl->Count(); 1470 if(bUsed) 1471 { 1472 SwAutoFmtGetDocNode aGetHt( &GetNodes() ); 1473 for ( sal_uInt16 i = nCount; i; ) 1474 { 1475 if((*pTblFrmFmtTbl)[--i]->GetInfo( aGetHt )) 1476 1477 --nCount; 1478 } 1479 } 1480 1481 return nCount; 1482 } 1483 1484 1485 SwFrmFmt& SwDoc::GetTblFrmFmt(sal_uInt16 nFmt, sal_Bool bUsed ) const 1486 { 1487 sal_uInt16 nRemoved = 0; 1488 if(bUsed) 1489 { 1490 SwAutoFmtGetDocNode aGetHt( &GetNodes() ); 1491 for ( sal_uInt16 i = 0; i <= nFmt; i++ ) 1492 { 1493 while ( (*pTblFrmFmtTbl)[ i + nRemoved]->GetInfo( aGetHt )) 1494 { 1495 nRemoved++; 1496 } 1497 } 1498 } 1499 return *((*pTblFrmFmtTbl)[nRemoved + nFmt]); 1500 } 1501 1502 SwTableFmt* SwDoc::MakeTblFrmFmt( const String &rFmtName, 1503 SwFrmFmt *pDerivedFrom ) 1504 { 1505 SwTableFmt* pFmt = new SwTableFmt( GetAttrPool(), rFmtName, pDerivedFrom ); 1506 pTblFrmFmtTbl->Insert( pFmt, pTblFrmFmtTbl->Count() ); 1507 SetModified(); 1508 1509 return pFmt; 1510 } 1511 1512 SwFrmFmt *SwDoc::MakeFrmFmt(const String &rFmtName, 1513 SwFrmFmt *pDerivedFrom, 1514 sal_Bool bBroadcast, sal_Bool bAuto) 1515 { 1516 1517 SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom ); 1518 1519 pFmt->SetAuto(bAuto); 1520 pFrmFmtTbl->Insert( pFmt, pFrmFmtTbl->Count()); 1521 SetModified(); 1522 1523 if (bBroadcast) 1524 { 1525 BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_PARA, 1526 SFX_STYLESHEET_CREATED); 1527 1528 if (GetIDocumentUndoRedo().DoesUndo()) 1529 { 1530 SwUndo * pUndo = new SwUndoFrmFmtCreate(pFmt, pDerivedFrom, this); 1531 1532 GetIDocumentUndoRedo().AppendUndo(pUndo); 1533 } 1534 } 1535 1536 return pFmt; 1537 } 1538 1539 SwFmt *SwDoc::_MakeFrmFmt(const String &rFmtName, 1540 SwFmt *pDerivedFrom, 1541 sal_Bool bBroadcast, sal_Bool bAuto) 1542 { 1543 SwFrmFmt *pFrmFmt = dynamic_cast<SwFrmFmt*>(pDerivedFrom); 1544 pFrmFmt = MakeFrmFmt( rFmtName, pFrmFmt, bBroadcast, bAuto ); 1545 return dynamic_cast<SwFmt*>(pFrmFmt); 1546 } 1547 1548 1549 // --> OD 2005-01-13 #i40550# - add parameter <bAuto> - not relevant 1550 SwCharFmt *SwDoc::MakeCharFmt( const String &rFmtName, 1551 SwCharFmt *pDerivedFrom, 1552 sal_Bool bBroadcast, 1553 sal_Bool ) 1554 // <-- 1555 { 1556 SwCharFmt *pFmt = new SwCharFmt( GetAttrPool(), rFmtName, pDerivedFrom ); 1557 pCharFmtTbl->Insert( pFmt, pCharFmtTbl->Count() ); 1558 pFmt->SetAuto( sal_False ); 1559 SetModified(); 1560 1561 if (GetIDocumentUndoRedo().DoesUndo()) 1562 { 1563 SwUndo * pUndo = new SwUndoCharFmtCreate(pFmt, pDerivedFrom, this); 1564 1565 GetIDocumentUndoRedo().AppendUndo(pUndo); 1566 } 1567 1568 if (bBroadcast) 1569 { 1570 BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_CHAR, 1571 SFX_STYLESHEET_CREATED); 1572 } 1573 1574 return pFmt; 1575 } 1576 1577 SwFmt *SwDoc::_MakeCharFmt(const String &rFmtName, 1578 SwFmt *pDerivedFrom, 1579 sal_Bool bBroadcast, sal_Bool bAuto) 1580 { 1581 SwCharFmt *pCharFmt = dynamic_cast<SwCharFmt*>(pDerivedFrom); 1582 pCharFmt = MakeCharFmt( rFmtName, pCharFmt, bBroadcast, bAuto ); 1583 return dynamic_cast<SwFmt*>(pCharFmt); 1584 } 1585 1586 1587 /* 1588 * Erzeugen der FormatCollections 1589 */ 1590 // TXT 1591 // --> OD 2005-01-13 #i40550# - add parameter <bAuto> - not relevant 1592 SwTxtFmtColl* SwDoc::MakeTxtFmtColl( const String &rFmtName, 1593 SwTxtFmtColl *pDerivedFrom, 1594 sal_Bool bBroadcast, 1595 sal_Bool ) 1596 // <-- 1597 { 1598 SwTxtFmtColl *pFmtColl = new SwTxtFmtColl( GetAttrPool(), rFmtName, 1599 pDerivedFrom ); 1600 pTxtFmtCollTbl->Insert(pFmtColl, pTxtFmtCollTbl->Count()); 1601 pFmtColl->SetAuto( sal_False ); 1602 SetModified(); 1603 1604 if (GetIDocumentUndoRedo().DoesUndo()) 1605 { 1606 SwUndo * pUndo = new SwUndoTxtFmtCollCreate(pFmtColl, pDerivedFrom, 1607 this); 1608 GetIDocumentUndoRedo().AppendUndo(pUndo); 1609 } 1610 1611 if (bBroadcast) 1612 BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_PARA, 1613 SFX_STYLESHEET_CREATED); 1614 1615 return pFmtColl; 1616 } 1617 1618 SwFmt *SwDoc::_MakeTxtFmtColl(const String &rFmtName, 1619 SwFmt *pDerivedFrom, 1620 sal_Bool bBroadcast, sal_Bool bAuto) 1621 { 1622 SwTxtFmtColl *pTxtFmtColl = dynamic_cast<SwTxtFmtColl*>(pDerivedFrom); 1623 pTxtFmtColl = MakeTxtFmtColl( rFmtName, pTxtFmtColl, bBroadcast, bAuto ); 1624 return dynamic_cast<SwFmt*>(pTxtFmtColl); 1625 } 1626 1627 1628 //FEATURE::CONDCOLL 1629 SwConditionTxtFmtColl* SwDoc::MakeCondTxtFmtColl( const String &rFmtName, 1630 SwTxtFmtColl *pDerivedFrom, 1631 sal_Bool bBroadcast) 1632 { 1633 SwConditionTxtFmtColl*pFmtColl = new SwConditionTxtFmtColl( GetAttrPool(), 1634 rFmtName, pDerivedFrom ); 1635 pTxtFmtCollTbl->Insert(pFmtColl, pTxtFmtCollTbl->Count()); 1636 pFmtColl->SetAuto( sal_False ); 1637 SetModified(); 1638 1639 if (bBroadcast) 1640 BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_PARA, 1641 SFX_STYLESHEET_CREATED); 1642 1643 return pFmtColl; 1644 } 1645 //FEATURE::CONDCOLL 1646 1647 // GRF 1648 1649 SwGrfFmtColl* SwDoc::MakeGrfFmtColl( const String &rFmtName, 1650 SwGrfFmtColl *pDerivedFrom ) 1651 { 1652 SwGrfFmtColl *pFmtColl = new SwGrfFmtColl( GetAttrPool(), rFmtName, 1653 pDerivedFrom ); 1654 pGrfFmtCollTbl->Insert( pFmtColl, pGrfFmtCollTbl->Count() ); 1655 pFmtColl->SetAuto( sal_False ); 1656 SetModified(); 1657 return pFmtColl; 1658 } 1659 1660 void SwDoc::DelTxtFmtColl(sal_uInt16 nFmtColl, sal_Bool bBroadcast) 1661 { 1662 ASSERT( nFmtColl, "Remove fuer Coll 0." ); 1663 1664 // Wer hat die zu loeschende als Next 1665 SwTxtFmtColl *pDel = (*pTxtFmtCollTbl)[nFmtColl]; 1666 if( pDfltTxtFmtColl == pDel ) 1667 return; // default nie loeschen !! 1668 1669 if (bBroadcast) 1670 BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_PARA, 1671 SFX_STYLESHEET_ERASED); 1672 1673 if (GetIDocumentUndoRedo().DoesUndo()) 1674 { 1675 SwUndoTxtFmtCollDelete * pUndo = 1676 new SwUndoTxtFmtCollDelete(pDel, this); 1677 1678 GetIDocumentUndoRedo().AppendUndo(pUndo); 1679 } 1680 1681 // Die FmtColl austragen 1682 pTxtFmtCollTbl->Remove(nFmtColl); 1683 // Next korrigieren 1684 pTxtFmtCollTbl->ForEach( 1, pTxtFmtCollTbl->Count(), 1685 &SetTxtFmtCollNext, pDel ); 1686 delete pDel; 1687 SetModified(); 1688 } 1689 1690 void SwDoc::DelTxtFmtColl( SwTxtFmtColl *pColl, sal_Bool bBroadcast ) 1691 { 1692 sal_uInt16 nFmt = pTxtFmtCollTbl->GetPos( pColl ); 1693 ASSERT( USHRT_MAX != nFmt, "Collection not found," ); 1694 DelTxtFmtColl( nFmt, bBroadcast ); 1695 } 1696 1697 sal_Bool lcl_SetTxtFmtColl( const SwNodePtr& rpNode, void* pArgs ) 1698 { 1699 SwCntntNode* pCNd = (SwCntntNode*) rpNode->GetTxtNode(); 1700 if ( pCNd ) 1701 { 1702 ParaRstFmt* pPara = (ParaRstFmt*) pArgs; 1703 1704 SwTxtFmtColl* pFmt = static_cast< SwTxtFmtColl* >( pPara->pFmtColl ); 1705 if ( pPara->bReset ) 1706 { 1707 1708 lcl_RstAttr( pCNd, pPara ); 1709 1710 // check, if paragraph style has changed 1711 if ( pPara->bResetListAttrs && 1712 pFmt != pCNd->GetFmtColl() && 1713 pFmt->GetItemState( RES_PARATR_NUMRULE ) == SFX_ITEM_SET ) 1714 { 1715 // --> OD 2009-09-07 #b6876367# 1716 // Check, if the list style of the paragraph will change. 1717 bool bChangeOfListStyleAtParagraph( true ); 1718 SwTxtNode* pTNd( dynamic_cast<SwTxtNode*>(pCNd) ); 1719 ASSERT( pTNd, 1720 "<lcl_SetTxtFmtColl(..)> - text node expected -> crash" ); 1721 { 1722 SwNumRule* pNumRuleAtParagraph( pTNd->GetNumRule() ); 1723 if ( pNumRuleAtParagraph ) 1724 { 1725 const SwNumRuleItem& rNumRuleItemAtParagraphStyle = 1726 pFmt->GetNumRule(); 1727 if ( rNumRuleItemAtParagraphStyle.GetValue() == 1728 pNumRuleAtParagraph->GetName() ) 1729 { 1730 bChangeOfListStyleAtParagraph = false; 1731 } 1732 } 1733 } 1734 1735 if ( bChangeOfListStyleAtParagraph ) 1736 { 1737 std::auto_ptr< SwRegHistory > pRegH; 1738 if ( pPara->pHistory ) 1739 { 1740 pRegH.reset( new SwRegHistory( pTNd, *pTNd, pPara->pHistory ) ); 1741 } 1742 1743 pCNd->ResetAttr( RES_PARATR_NUMRULE ); 1744 1745 // reset all list attributes 1746 pCNd->ResetAttr( RES_PARATR_LIST_LEVEL ); 1747 pCNd->ResetAttr( RES_PARATR_LIST_ISRESTART ); 1748 pCNd->ResetAttr( RES_PARATR_LIST_RESTARTVALUE ); 1749 pCNd->ResetAttr( RES_PARATR_LIST_ISCOUNTED ); 1750 pCNd->ResetAttr( RES_PARATR_LIST_ID ); 1751 } 1752 } 1753 } 1754 1755 // erst in die History aufnehmen, damit ggfs. alte Daten 1756 // gesichert werden koennen 1757 if( pPara->pHistory ) 1758 pPara->pHistory->Add( pCNd->GetFmtColl(), pCNd->GetIndex(), 1759 ND_TEXTNODE ); 1760 1761 pCNd->ChgFmtColl( pFmt ); 1762 1763 pPara->nWhich++; 1764 } 1765 return sal_True; 1766 } 1767 1768 1769 sal_Bool SwDoc::SetTxtFmtColl( 1770 const SwPaM &rRg, 1771 SwTxtFmtColl *pFmt, 1772 const bool bReset, 1773 const bool bResetListAttrs ) 1774 { 1775 SwDataChanged aTmp( rRg, 0 ); 1776 const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End(); 1777 SwHistory* pHst = 0; 1778 sal_Bool bRet = sal_True; 1779 1780 if (GetIDocumentUndoRedo().DoesUndo()) 1781 { 1782 SwUndoFmtColl* pUndo = new SwUndoFmtColl( rRg, pFmt, 1783 bReset, 1784 bResetListAttrs ); 1785 pHst = pUndo->GetHistory(); 1786 GetIDocumentUndoRedo().AppendUndo(pUndo); 1787 } 1788 1789 ParaRstFmt aPara( pStt, pEnd, pHst ); 1790 aPara.pFmtColl = pFmt; 1791 aPara.bReset = bReset; 1792 aPara.bResetListAttrs = bResetListAttrs; 1793 1794 GetNodes().ForEach( pStt->nNode.GetIndex(), pEnd->nNode.GetIndex()+1, 1795 lcl_SetTxtFmtColl, &aPara ); 1796 if ( !aPara.nWhich ) 1797 bRet = sal_False; // keinen gueltigen Node gefunden 1798 1799 if ( bRet ) 1800 { 1801 SetModified(); 1802 } 1803 1804 return bRet; 1805 } 1806 1807 1808 // ---- Kopiere die Formate in sich selbst (SwDoc) ---------------------- 1809 1810 SwFmt* SwDoc::CopyFmt( const SwFmt& rFmt, 1811 const SvPtrarr& rFmtArr, 1812 FNCopyFmt fnCopyFmt, const SwFmt& rDfltFmt ) 1813 { 1814 // kein-Autoformat || default Format || Collection-Format 1815 // dann suche danach. 1816 if( !rFmt.IsAuto() || !rFmt.GetRegisteredIn() ) 1817 for( sal_uInt16 n = 0; n < rFmtArr.Count(); n++ ) 1818 { 1819 // ist die Vorlage schon im Doc vorhanden ?? 1820 if( ((SwFmt*)rFmtArr[n])->GetName().Equals( rFmt.GetName() )) 1821 return (SwFmt*)rFmtArr[n]; 1822 } 1823 1824 // suche erstmal nach dem "Parent" 1825 SwFmt* pParent = (SwFmt*)&rDfltFmt; 1826 if( rFmt.DerivedFrom() && pParent != rFmt.DerivedFrom() ) 1827 pParent = CopyFmt( *rFmt.DerivedFrom(), rFmtArr, 1828 fnCopyFmt, rDfltFmt ); 1829 1830 // erzeuge das Format und kopiere die Attribute 1831 // --> OD 2005-01-13 #i40550# 1832 SwFmt* pNewFmt = (this->*fnCopyFmt)( rFmt.GetName(), pParent, sal_False, sal_True ); 1833 // <-- 1834 pNewFmt->SetAuto( rFmt.IsAuto() ); 1835 pNewFmt->CopyAttrs( rFmt, sal_True ); // kopiere Attribute 1836 1837 pNewFmt->SetPoolFmtId( rFmt.GetPoolFmtId() ); 1838 pNewFmt->SetPoolHelpId( rFmt.GetPoolHelpId() ); 1839 1840 // HelpFile-Id immer auf dflt setzen !! 1841 pNewFmt->SetPoolHlpFileId( UCHAR_MAX ); 1842 1843 return pNewFmt; 1844 } 1845 1846 1847 // ---- kopiere das Frame-Format -------- 1848 SwFrmFmt* SwDoc::CopyFrmFmt( const SwFrmFmt& rFmt ) 1849 { 1850 1851 return (SwFrmFmt*)CopyFmt( rFmt, *GetFrmFmts(), &SwDoc::_MakeFrmFmt, 1852 *GetDfltFrmFmt() ); 1853 } 1854 1855 // ---- kopiere das Char-Format -------- 1856 SwCharFmt* SwDoc::CopyCharFmt( const SwCharFmt& rFmt ) 1857 { 1858 return (SwCharFmt*)CopyFmt( rFmt, *GetCharFmts(), 1859 &SwDoc::_MakeCharFmt, 1860 *GetDfltCharFmt() ); 1861 } 1862 1863 1864 // --- Kopiere TextNodes ---- 1865 1866 SwTxtFmtColl* SwDoc::CopyTxtColl( const SwTxtFmtColl& rColl ) 1867 { 1868 SwTxtFmtColl* pNewColl = FindTxtFmtCollByName( rColl.GetName() ); 1869 if( pNewColl ) 1870 return pNewColl; 1871 1872 // suche erstmal nach dem "Parent" 1873 SwTxtFmtColl* pParent = pDfltTxtFmtColl; 1874 if( pParent != rColl.DerivedFrom() ) 1875 pParent = CopyTxtColl( *(SwTxtFmtColl*)rColl.DerivedFrom() ); 1876 1877 1878 //FEATURE::CONDCOLL 1879 if( RES_CONDTXTFMTCOLL == rColl.Which() ) 1880 { 1881 pNewColl = new SwConditionTxtFmtColl( GetAttrPool(), rColl.GetName(), 1882 pParent); 1883 pTxtFmtCollTbl->Insert( pNewColl, pTxtFmtCollTbl->Count() ); 1884 pNewColl->SetAuto( sal_False ); 1885 SetModified(); 1886 1887 // Kopiere noch die Bedingungen 1888 ((SwConditionTxtFmtColl*)pNewColl)->SetConditions( 1889 ((SwConditionTxtFmtColl&)rColl).GetCondColls() ); 1890 } 1891 else 1892 //FEATURE::CONDCOLL 1893 pNewColl = MakeTxtFmtColl( rColl.GetName(), pParent ); 1894 1895 // kopiere jetzt noch die Auto-Formate oder kopiere die Attribute 1896 pNewColl->CopyAttrs( rColl, sal_True ); 1897 1898 // setze noch den Outline-Level 1899 if ( rColl.IsAssignedToListLevelOfOutlineStyle() ) 1900 pNewColl->AssignToListLevelOfOutlineStyle( rColl.GetAssignedOutlineStyleLevel() ); 1901 1902 pNewColl->SetPoolFmtId( rColl.GetPoolFmtId() ); 1903 pNewColl->SetPoolHelpId( rColl.GetPoolHelpId() ); 1904 1905 // HelpFile-Id immer auf dflt setzen !! 1906 pNewColl->SetPoolHlpFileId( UCHAR_MAX ); 1907 1908 if( &rColl.GetNextTxtFmtColl() != &rColl ) 1909 pNewColl->SetNextTxtFmtColl( *CopyTxtColl( rColl.GetNextTxtFmtColl() )); 1910 1911 // ggfs. die NumRule erzeugen 1912 if( this != rColl.GetDoc() ) 1913 { 1914 const SfxPoolItem* pItem; 1915 if( SFX_ITEM_SET == pNewColl->GetItemState( RES_PARATR_NUMRULE, 1916 sal_False, &pItem )) 1917 { 1918 const SwNumRule* pRule; 1919 const String& rName = ((SwNumRuleItem*)pItem)->GetValue(); 1920 if( rName.Len() && 1921 0 != ( pRule = rColl.GetDoc()->FindNumRulePtr( rName )) && 1922 !pRule->IsAutoRule() ) 1923 { 1924 SwNumRule* pDestRule = FindNumRulePtr( rName ); 1925 if( pDestRule ) 1926 pDestRule->SetInvalidRule( sal_True ); 1927 else 1928 MakeNumRule( rName, pRule ); 1929 } 1930 } 1931 } 1932 return pNewColl; 1933 } 1934 1935 // --- Kopiere GrafikNodes ---- 1936 1937 SwGrfFmtColl* SwDoc::CopyGrfColl( const SwGrfFmtColl& rColl ) 1938 { 1939 SwGrfFmtColl* pNewColl = FindGrfFmtCollByName( rColl.GetName() ); 1940 if( pNewColl ) 1941 return pNewColl; 1942 1943 // suche erstmal nach dem "Parent" 1944 SwGrfFmtColl* pParent = pDfltGrfFmtColl; 1945 if( pParent != rColl.DerivedFrom() ) 1946 pParent = CopyGrfColl( *(SwGrfFmtColl*)rColl.DerivedFrom() ); 1947 1948 // falls nicht, so kopiere sie 1949 pNewColl = MakeGrfFmtColl( rColl.GetName(), pParent ); 1950 1951 // noch die Attribute kopieren 1952 pNewColl->CopyAttrs( rColl ); 1953 1954 pNewColl->SetPoolFmtId( rColl.GetPoolFmtId() ); 1955 pNewColl->SetPoolHelpId( rColl.GetPoolHelpId() ); 1956 1957 // HelpFile-Id immer auf dflt setzen !! 1958 pNewColl->SetPoolHlpFileId( UCHAR_MAX ); 1959 1960 return pNewColl; 1961 } 1962 1963 SwPageDesc* lcl_FindPageDesc( const SwPageDescs& rArr, const String& rName ) 1964 { 1965 for( sal_uInt16 n = rArr.Count(); n; ) 1966 { 1967 SwPageDesc* pDesc = rArr[ --n ]; 1968 if( pDesc->GetName() == rName ) 1969 return pDesc; 1970 } 1971 return 0; 1972 } 1973 1974 void SwDoc::CopyFmtArr( const SvPtrarr& rSourceArr, 1975 SvPtrarr& rDestArr, 1976 FNCopyFmt fnCopyFmt, 1977 SwFmt& rDfltFmt ) 1978 { 1979 sal_uInt16 nSrc; 1980 SwFmt* pSrc, *pDest; 1981 1982 // 1. Schritt alle Formate anlegen (das 0. ueberspringen - Default!) 1983 for( nSrc = rSourceArr.Count(); nSrc > 1; ) 1984 { 1985 pSrc = (SwFmt*)rSourceArr[ --nSrc ]; 1986 if( pSrc->IsDefault() || pSrc->IsAuto() ) 1987 continue; 1988 1989 if( 0 == FindFmtByName( rDestArr, pSrc->GetName() ) ) 1990 { 1991 if( RES_CONDTXTFMTCOLL == pSrc->Which() ) 1992 MakeCondTxtFmtColl( pSrc->GetName(), (SwTxtFmtColl*)&rDfltFmt ); 1993 else 1994 // --> OD 2005-01-13 #i40550# 1995 (this->*fnCopyFmt)( pSrc->GetName(), &rDfltFmt, sal_False, sal_True ); 1996 // <-- 1997 } 1998 } 1999 2000 // 2. Schritt alle Attribute kopieren, richtige Parents setzen 2001 for( nSrc = rSourceArr.Count(); nSrc > 1; ) 2002 { 2003 pSrc = (SwFmt*)rSourceArr[ --nSrc ]; 2004 if( pSrc->IsDefault() || pSrc->IsAuto() ) 2005 continue; 2006 2007 pDest = FindFmtByName( rDestArr, pSrc->GetName() ); 2008 pDest->SetAuto( sal_False ); 2009 pDest->DelDiffs( *pSrc ); 2010 2011 // #i94285#: existing <SwFmtPageDesc> instance, before copying attributes 2012 const SfxPoolItem* pItem; 2013 if( &GetAttrPool() != pSrc->GetAttrSet().GetPool() && 2014 SFX_ITEM_SET == pSrc->GetAttrSet().GetItemState( 2015 RES_PAGEDESC, sal_False, &pItem ) && 2016 ((SwFmtPageDesc*)pItem)->GetPageDesc() ) 2017 { 2018 SwFmtPageDesc aPageDesc( *(SwFmtPageDesc*)pItem ); 2019 const String& rNm = aPageDesc.GetPageDesc()->GetName(); 2020 SwPageDesc* pPageDesc = ::lcl_FindPageDesc( aPageDescs, rNm ); 2021 if( !pPageDesc ) 2022 { 2023 pPageDesc = aPageDescs[ MakePageDesc( rNm ) ]; 2024 } 2025 aPageDesc.RegisterToPageDesc( *pPageDesc ); 2026 SwAttrSet aTmpAttrSet( pSrc->GetAttrSet() ); 2027 aTmpAttrSet.Put( aPageDesc ); 2028 pDest->SetFmtAttr( aTmpAttrSet ); 2029 } 2030 else 2031 { 2032 pDest->SetFmtAttr( pSrc->GetAttrSet() ); 2033 } 2034 2035 pDest->SetPoolFmtId( pSrc->GetPoolFmtId() ); 2036 pDest->SetPoolHelpId( pSrc->GetPoolHelpId() ); 2037 2038 // HelpFile-Id immer auf dflt setzen !! 2039 pDest->SetPoolHlpFileId( UCHAR_MAX ); 2040 2041 if( pSrc->DerivedFrom() ) 2042 pDest->SetDerivedFrom( FindFmtByName( rDestArr, 2043 pSrc->DerivedFrom()->GetName() ) ); 2044 if( RES_TXTFMTCOLL == pSrc->Which() || 2045 RES_CONDTXTFMTCOLL == pSrc->Which() ) 2046 { 2047 SwTxtFmtColl* pSrcColl = (SwTxtFmtColl*)pSrc, 2048 * pDstColl = (SwTxtFmtColl*)pDest; 2049 if( &pSrcColl->GetNextTxtFmtColl() != pSrcColl ) 2050 pDstColl->SetNextTxtFmtColl( *(SwTxtFmtColl*)FindFmtByName( 2051 rDestArr, pSrcColl->GetNextTxtFmtColl().GetName() ) ); 2052 2053 // setze noch den Outline-Level 2054 if(pSrcColl->IsAssignedToListLevelOfOutlineStyle()) 2055 pDstColl->AssignToListLevelOfOutlineStyle(pSrcColl->GetAssignedOutlineStyleLevel()); 2056 2057 //FEATURE::CONDCOLL 2058 if( RES_CONDTXTFMTCOLL == pSrc->Which() ) 2059 // Kopiere noch die Bedingungen 2060 // aber erst die alten loeschen! 2061 ((SwConditionTxtFmtColl*)pDstColl)->SetConditions( 2062 ((SwConditionTxtFmtColl*)pSrc)->GetCondColls() ); 2063 //FEATURE::CONDCOLL 2064 } 2065 } 2066 } 2067 2068 void SwDoc::CopyPageDescHeaderFooterImpl( bool bCpyHeader, 2069 const SwFrmFmt& rSrcFmt, SwFrmFmt& rDestFmt ) 2070 { 2071 // jetzt noch Header-/Footer-Attribute richtig behandeln 2072 // Contenten Nodes Dokumentuebergreifend kopieren! 2073 sal_uInt16 nAttr = static_cast<sal_uInt16>( bCpyHeader ? RES_HEADER : RES_FOOTER ); 2074 const SfxPoolItem* pItem; 2075 if( SFX_ITEM_SET != rSrcFmt.GetAttrSet().GetItemState( nAttr, sal_False, &pItem )) 2076 return ; 2077 2078 // Im Header steht noch der Verweis auf das Format aus dem 2079 // anderen Document!! 2080 SfxPoolItem* pNewItem = pItem->Clone(); 2081 2082 SwFrmFmt* pOldFmt; 2083 if( bCpyHeader ) 2084 pOldFmt = ((SwFmtHeader*)pNewItem)->GetHeaderFmt(); 2085 else 2086 pOldFmt = ((SwFmtFooter*)pNewItem)->GetFooterFmt(); 2087 2088 if( pOldFmt ) 2089 { 2090 SwFrmFmt* pNewFmt = new SwFrmFmt( GetAttrPool(), "CpyDesc", 2091 GetDfltFrmFmt() ); 2092 pNewFmt->CopyAttrs( *pOldFmt, sal_True ); 2093 2094 if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState( 2095 RES_CNTNT, sal_False, &pItem )) 2096 { 2097 SwFmtCntnt* pCntnt = (SwFmtCntnt*)pItem; 2098 if( pCntnt->GetCntntIdx() ) 2099 { 2100 SwNodeIndex aTmpIdx( GetNodes().GetEndOfAutotext() ); 2101 const SwNodes& rSrcNds = rSrcFmt.GetDoc()->GetNodes(); 2102 SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmpIdx, 2103 bCpyHeader 2104 ? SwHeaderStartNode 2105 : SwFooterStartNode ); 2106 const SwNode& rCSttNd = pCntnt->GetCntntIdx()->GetNode(); 2107 SwNodeRange aRg( rCSttNd, 0, *rCSttNd.EndOfSectionNode() ); 2108 aTmpIdx = *pSttNd->EndOfSectionNode(); 2109 rSrcNds._Copy( aRg, aTmpIdx ); 2110 aTmpIdx = *pSttNd; 2111 rSrcFmt.GetDoc()->CopyFlyInFlyImpl( aRg, 0, aTmpIdx ); 2112 pNewFmt->SetFmtAttr( SwFmtCntnt( pSttNd )); 2113 } 2114 else 2115 pNewFmt->ResetFmtAttr( RES_CNTNT ); 2116 } 2117 if( bCpyHeader ) 2118 ((SwFmtHeader*)pNewItem)->RegisterToFormat(*pNewFmt); 2119 else 2120 ((SwFmtFooter*)pNewItem)->RegisterToFormat(*pNewFmt); 2121 rDestFmt.SetFmtAttr( *pNewItem ); 2122 } 2123 delete pNewItem; 2124 } 2125 2126 void SwDoc::CopyPageDesc( const SwPageDesc& rSrcDesc, SwPageDesc& rDstDesc, 2127 sal_Bool bCopyPoolIds ) 2128 { 2129 sal_Bool bNotifyLayout = sal_False; 2130 SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219 2131 2132 rDstDesc.SetLandscape( rSrcDesc.GetLandscape() ); 2133 rDstDesc.SetNumType( rSrcDesc.GetNumType() ); 2134 if( rDstDesc.ReadUseOn() != rSrcDesc.ReadUseOn() ) 2135 { 2136 rDstDesc.WriteUseOn( rSrcDesc.ReadUseOn() ); 2137 bNotifyLayout = sal_True; 2138 } 2139 2140 if( bCopyPoolIds ) 2141 { 2142 rDstDesc.SetPoolFmtId( rSrcDesc.GetPoolFmtId() ); 2143 rDstDesc.SetPoolHelpId( rSrcDesc.GetPoolHelpId() ); 2144 // HelpFile-Id immer auf dflt setzen !! 2145 rDstDesc.SetPoolHlpFileId( UCHAR_MAX ); 2146 } 2147 2148 if( rSrcDesc.GetFollow() != &rSrcDesc ) 2149 { 2150 SwPageDesc* pFollow = ::lcl_FindPageDesc( aPageDescs, 2151 rSrcDesc.GetFollow()->GetName() ); 2152 if( !pFollow ) 2153 { 2154 // dann mal kopieren 2155 sal_uInt16 nPos = MakePageDesc( rSrcDesc.GetFollow()->GetName() ); 2156 pFollow = aPageDescs[ nPos ]; 2157 CopyPageDesc( *rSrcDesc.GetFollow(), *pFollow ); 2158 } 2159 rDstDesc.SetFollow( pFollow ); 2160 bNotifyLayout = sal_True; 2161 } 2162 2163 // die Header/Footer-Attribute werden gesondert kopiert, die Content- 2164 // Sections muessen vollstaendig mitgenommen werden! 2165 { 2166 SfxItemSet aAttrSet( rSrcDesc.GetMaster().GetAttrSet() ); 2167 aAttrSet.ClearItem( RES_HEADER ); 2168 aAttrSet.ClearItem( RES_FOOTER ); 2169 2170 rDstDesc.GetMaster().DelDiffs( aAttrSet ); 2171 rDstDesc.GetMaster().SetFmtAttr( aAttrSet ); 2172 2173 aAttrSet.ClearItem(); 2174 aAttrSet.Put( rSrcDesc.GetLeft().GetAttrSet() ); 2175 aAttrSet.ClearItem( RES_HEADER ); 2176 aAttrSet.ClearItem( RES_FOOTER ); 2177 2178 rDstDesc.GetLeft().DelDiffs( aAttrSet ); 2179 rDstDesc.GetLeft().SetFmtAttr( aAttrSet ); 2180 } 2181 2182 CopyHeader( rSrcDesc.GetMaster(), rDstDesc.GetMaster() ); 2183 CopyFooter( rSrcDesc.GetMaster(), rDstDesc.GetMaster() ); 2184 if( !rDstDesc.IsHeaderShared() ) 2185 CopyHeader( rSrcDesc.GetLeft(), rDstDesc.GetLeft() ); 2186 else 2187 rDstDesc.GetLeft().SetFmtAttr( rDstDesc.GetMaster().GetHeader() ); 2188 2189 if( !rDstDesc.IsFooterShared() ) 2190 CopyFooter( rSrcDesc.GetLeft(), rDstDesc.GetLeft() ); 2191 else 2192 rDstDesc.GetLeft().SetFmtAttr( rDstDesc.GetMaster().GetFooter() ); 2193 2194 if( bNotifyLayout && pTmpRoot ) 2195 { 2196 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080225 2197 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs));//swmod 080226 2198 } 2199 2200 //Wenn sich FussnotenInfo veraendert, so werden die Seiten 2201 //angetriggert. 2202 if( !(rDstDesc.GetFtnInfo() == rSrcDesc.GetFtnInfo()) ) 2203 { 2204 rDstDesc.SetFtnInfo( rSrcDesc.GetFtnInfo() ); 2205 SwMsgPoolItem aInfo( RES_PAGEDESC_FTNINFO ); 2206 { 2207 rDstDesc.GetMaster().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) ); 2208 } 2209 { 2210 rDstDesc.GetLeft().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) ); 2211 } 2212 } 2213 } 2214 2215 void SwDoc::ReplaceStyles( SwDoc& rSource ) 2216 { 2217 ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo()); 2218 2219 CopyFmtArr( *rSource.pCharFmtTbl, *pCharFmtTbl, 2220 &SwDoc::_MakeCharFmt, *pDfltCharFmt ); 2221 CopyFmtArr( *rSource.pFrmFmtTbl, *pFrmFmtTbl, 2222 &SwDoc::_MakeFrmFmt, *pDfltFrmFmt ); 2223 CopyFmtArr( *rSource.pTxtFmtCollTbl, *pTxtFmtCollTbl, 2224 &SwDoc::_MakeTxtFmtColl, *pDfltTxtFmtColl ); 2225 2226 // und jetzt noch die Seiten-Vorlagen 2227 sal_uInt16 nCnt = rSource.aPageDescs.Count(); 2228 if( nCnt ) 2229 { 2230 // ein anderes Doc -> Numberformatter muessen gemergt werden 2231 SwTblNumFmtMerge aTNFM( rSource, *this ); 2232 2233 // 1. Schritt alle Formate anlegen (das 0. ueberspringen - Default!) 2234 while( nCnt ) 2235 { 2236 SwPageDesc *pSrc = rSource.aPageDescs[ --nCnt ]; 2237 if( 0 == ::lcl_FindPageDesc( aPageDescs, pSrc->GetName() ) ) 2238 MakePageDesc( pSrc->GetName() ); 2239 } 2240 2241 // 2. Schritt alle Attribute kopieren, richtige Parents setzen 2242 for( nCnt = rSource.aPageDescs.Count(); nCnt; ) 2243 { 2244 SwPageDesc *pSrc = rSource.aPageDescs[ --nCnt ]; 2245 CopyPageDesc( *pSrc, *::lcl_FindPageDesc( aPageDescs, pSrc->GetName() )); 2246 } 2247 } 2248 2249 //JP 08.04.99: und dann sind da noch die Numerierungs-Vorlagen 2250 nCnt = rSource.GetNumRuleTbl().Count(); 2251 if( nCnt ) 2252 { 2253 const SwNumRuleTbl& rArr = rSource.GetNumRuleTbl(); 2254 for( sal_uInt16 n = 0; n < nCnt; ++n ) 2255 { 2256 const SwNumRule& rR = *rArr[ n ]; 2257 if( !rR.IsAutoRule() ) 2258 { 2259 SwNumRule* pNew = FindNumRulePtr( rR.GetName()); 2260 if( pNew ) 2261 pNew->CopyNumRule( this, rR ); 2262 else 2263 MakeNumRule( rR.GetName(), &rR ); 2264 } 2265 } 2266 } 2267 2268 if (undoGuard.UndoWasEnabled()) 2269 { 2270 // nodes array was modified! 2271 GetIDocumentUndoRedo().DelAllUndoObj(); 2272 } 2273 2274 SetModified(); 2275 } 2276 2277 SwFmt* SwDoc::FindFmtByName( const SvPtrarr& rFmtArr, 2278 const String& rName ) const 2279 { 2280 SwFmt* pFnd = 0; 2281 for( sal_uInt16 n = 0; n < rFmtArr.Count(); n++ ) 2282 { 2283 // ist die Vorlage schon im Doc vorhanden ?? 2284 if( ((SwFmt*)rFmtArr[n])->GetName() == rName ) 2285 { 2286 pFnd = (SwFmt*)rFmtArr[n]; 2287 break; 2288 } 2289 } 2290 return pFnd; 2291 } 2292 2293 void SwDoc::MoveLeftMargin( const SwPaM& rPam, sal_Bool bRight, sal_Bool bModulus ) 2294 { 2295 SwHistory* pHistory = 0; 2296 if (GetIDocumentUndoRedo().DoesUndo()) 2297 { 2298 SwUndoMoveLeftMargin* pUndo = new SwUndoMoveLeftMargin( rPam, bRight, 2299 bModulus ); 2300 pHistory = &pUndo->GetHistory(); 2301 GetIDocumentUndoRedo().AppendUndo( pUndo ); 2302 } 2303 2304 const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDefault( RES_PARATR_TABSTOP ); 2305 sal_uInt16 nDefDist = rTabItem.Count() ? 2306 static_cast<sal_uInt16>(rTabItem[0].GetTabPos()) : 1134; 2307 const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End(); 2308 SwNodeIndex aIdx( rStt.nNode ); 2309 while( aIdx <= rEnd.nNode ) 2310 { 2311 SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode(); 2312 if( pTNd ) 2313 { 2314 SvxLRSpaceItem aLS( (SvxLRSpaceItem&)pTNd->SwCntntNode::GetAttr( RES_LR_SPACE ) ); 2315 2316 // --> FME 2008-09-16 #i93873# See also lcl_MergeListLevelIndentAsLRSpaceItem in thints.cxx 2317 if ( pTNd->AreListLevelIndentsApplicable() ) 2318 { 2319 const SwNumRule* pRule = pTNd->GetNumRule(); 2320 if ( pRule ) 2321 { 2322 const int nListLevel = pTNd->GetActualListLevel(); 2323 if ( nListLevel >= 0 ) 2324 { 2325 const SwNumFmt& rFmt = pRule->Get(static_cast<sal_uInt16>(nListLevel)); 2326 if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT ) 2327 { 2328 aLS.SetTxtLeft( rFmt.GetIndentAt() ); 2329 aLS.SetTxtFirstLineOfst( static_cast<short>(rFmt.GetFirstLineIndent()) ); 2330 } 2331 } 2332 } 2333 } 2334 2335 long nNext = aLS.GetTxtLeft(); 2336 if( bModulus ) 2337 nNext = ( nNext / nDefDist ) * nDefDist; 2338 2339 if( bRight ) 2340 nNext += nDefDist; 2341 else 2342 nNext -= nDefDist; 2343 2344 aLS.SetTxtLeft( nNext ); 2345 2346 SwRegHistory aRegH( pTNd, *pTNd, pHistory ); 2347 pTNd->SetAttr( aLS ); 2348 } 2349 aIdx++; 2350 } 2351 SetModified(); 2352 } 2353 2354 sal_Bool SwDoc::DontExpandFmt( const SwPosition& rPos, sal_Bool bFlag ) 2355 { 2356 sal_Bool bRet = sal_False; 2357 SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode(); 2358 if( pTxtNd ) 2359 { 2360 bRet = pTxtNd->DontExpandFmt( rPos.nContent, bFlag ); 2361 if( bRet && GetIDocumentUndoRedo().DoesUndo() ) 2362 { 2363 GetIDocumentUndoRedo().AppendUndo( new SwUndoDontExpandFmt(rPos) ); 2364 } 2365 } 2366 return bRet; 2367 } 2368 2369 SwTableBoxFmt* SwDoc::MakeTableBoxFmt() 2370 { 2371 SwTableBoxFmt* pFmt = new SwTableBoxFmt( GetAttrPool(), aEmptyStr, 2372 pDfltFrmFmt ); 2373 SetModified(); 2374 return pFmt; 2375 } 2376 2377 SwTableLineFmt* SwDoc::MakeTableLineFmt() 2378 { 2379 SwTableLineFmt* pFmt = new SwTableLineFmt( GetAttrPool(), aEmptyStr, 2380 pDfltFrmFmt ); 2381 SetModified(); 2382 return pFmt; 2383 } 2384 2385 void SwDoc::_CreateNumberFormatter() 2386 { 2387 RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722", "SwDoc::_CreateNumberFormatter" ); 2388 2389 ASSERT( !pNumberFormatter, "ist doch schon vorhanden" ); 2390 2391 2392 LanguageType eLang = LANGUAGE_SYSTEM; //System::GetLanguage(); 2393 /* ((const SvxLanguageItem&)GetAttrPool(). 2394 GetDefaultItem( RES_CHRATR_LANGUAGE )).GetLanguage(); 2395 */ 2396 Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); 2397 pNumberFormatter = new SvNumberFormatter( xMSF, eLang ); 2398 pNumberFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_FORMAT_INTL ); 2399 pNumberFormatter->SetYear2000(static_cast<sal_uInt16>(::utl::MiscCfg().GetYear2000())); 2400 2401 } 2402 2403 SwTblNumFmtMerge::SwTblNumFmtMerge( const SwDoc& rSrc, SwDoc& rDest ) 2404 : pNFmt( 0 ) 2405 { 2406 // ein anderes Doc -> Numberformatter muessen gemergt werden 2407 SvNumberFormatter* pN; 2408 if( &rSrc != &rDest && 0 != ( pN = ((SwDoc&)rSrc).GetNumberFormatter( sal_False ) )) 2409 ( pNFmt = rDest.GetNumberFormatter( sal_True ))->MergeFormatter( *pN ); 2410 2411 if( &rSrc != &rDest ) 2412 ((SwGetRefFieldType*)rSrc.GetSysFldType( RES_GETREFFLD ))-> 2413 MergeWithOtherDoc( rDest ); 2414 } 2415 2416 SwTblNumFmtMerge::~SwTblNumFmtMerge() 2417 { 2418 if( pNFmt ) 2419 pNFmt->ClearMergeTable(); 2420 } 2421 2422 2423 void SwDoc::SetTxtFmtCollByAutoFmt( const SwPosition& rPos, sal_uInt16 nPoolId, 2424 const SfxItemSet* pSet ) 2425 { 2426 SwPaM aPam( rPos ); 2427 SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode(); 2428 2429 if( mbIsAutoFmtRedline && pTNd ) 2430 { 2431 // dann das Redline Object anlegen 2432 const SwTxtFmtColl& rColl = *pTNd->GetTxtColl(); 2433 SwRedline* pRedl = new SwRedline( nsRedlineType_t::REDLINE_FMTCOLL, aPam ); 2434 pRedl->SetMark(); 2435 2436 // interressant sind nur die Items, die vom Set NICHT wieder 2437 // in den Node gesetzt werden. Also muss man die Differenz nehmen 2438 SwRedlineExtraData_FmtColl aExtraData( rColl.GetName(), 2439 rColl.GetPoolFmtId() ); 2440 if( pSet && pTNd->HasSwAttrSet() ) 2441 { 2442 SfxItemSet aTmp( *pTNd->GetpSwAttrSet() ); 2443 aTmp.Differentiate( *pSet ); 2444 // das Adjust Item behalten wir extra 2445 const SfxPoolItem* pItem; 2446 if( SFX_ITEM_SET == pTNd->GetpSwAttrSet()->GetItemState( 2447 RES_PARATR_ADJUST, sal_False, &pItem )) 2448 aTmp.Put( *pItem ); 2449 aExtraData.SetItemSet( aTmp ); 2450 } 2451 pRedl->SetExtraData( &aExtraData ); 2452 2453 // !!!!!!!!! Undo fehlt noch !!!!!!!!!!!!!!!!!! 2454 AppendRedline( pRedl, true ); 2455 } 2456 2457 SetTxtFmtColl( aPam, GetTxtCollFromPool( nPoolId ) ); 2458 2459 if( pSet && pTNd && pSet->Count() ) 2460 { 2461 aPam.SetMark(); 2462 aPam.GetMark()->nContent.Assign( pTNd, pTNd->GetTxt().Len() ); 2463 InsertItemSet( aPam, *pSet, 0 ); 2464 } 2465 } 2466 2467 void SwDoc::SetFmtItemByAutoFmt( const SwPaM& rPam, const SfxItemSet& rSet ) 2468 { 2469 SwTxtNode* pTNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode(); 2470 2471 RedlineMode_t eOld = GetRedlineMode(); 2472 2473 if( mbIsAutoFmtRedline && pTNd ) 2474 { 2475 // dann das Redline Object anlegen 2476 SwRedline* pRedl = new SwRedline( nsRedlineType_t::REDLINE_FORMAT, rPam ); 2477 if( !pRedl->HasMark() ) 2478 pRedl->SetMark(); 2479 2480 // interressant sind nur die Items, die vom Set NICHT wieder 2481 // in den Node gesetzt werden. Also muss man die Differenz nehmen 2482 SwRedlineExtraData_Format aExtraData( rSet ); 2483 2484 /* 2485 if( pSet && pTNd->HasSwAttrSet() ) 2486 { 2487 SfxItemSet aTmp( *pTNd->GetpSwAttrSet() ); 2488 aTmp.Differentiate( *pSet ); 2489 // das Adjust Item behalten wir extra 2490 const SfxPoolItem* pItem; 2491 if( SFX_ITEM_SET == pTNd->GetpSwAttrSet()->GetItemState( 2492 RES_PARATR_ADJUST, sal_False, &pItem )) 2493 aTmp.Put( *pItem ); 2494 aExtraData.SetItemSet( aTmp ); 2495 } 2496 */ 2497 pRedl->SetExtraData( &aExtraData ); 2498 2499 // !!!!!!!!! Undo fehlt noch !!!!!!!!!!!!!!!!!! 2500 AppendRedline( pRedl, true ); 2501 2502 SetRedlineMode_intern( (RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE)); 2503 } 2504 2505 InsertItemSet( rPam, rSet, nsSetAttrMode::SETATTR_DONTEXPAND ); 2506 SetRedlineMode_intern( eOld ); 2507 } 2508 2509 void SwDoc::ChgFmt(SwFmt & rFmt, const SfxItemSet & rSet) 2510 { 2511 if (GetIDocumentUndoRedo().DoesUndo()) 2512 { 2513 // copying <rSet> to <aSet> 2514 SfxItemSet aSet(rSet); 2515 // remove from <aSet> all items, which are already set at the format 2516 aSet.Differentiate(rFmt.GetAttrSet()); 2517 // <aSet> contains now all *new* items for the format 2518 2519 // copying current format item set to <aOldSet> 2520 SfxItemSet aOldSet(rFmt.GetAttrSet()); 2521 // insert new items into <aOldSet> 2522 aOldSet.Put(aSet); 2523 // invalidate all new items in <aOldSet> in order to clear these items, 2524 // if the undo action is triggered. 2525 { 2526 SfxItemIter aIter(aSet); 2527 2528 const SfxPoolItem * pItem = aIter.FirstItem(); 2529 while (pItem != NULL) 2530 { 2531 aOldSet.InvalidateItem(pItem->Which()); 2532 2533 pItem = aIter.NextItem(); 2534 } 2535 } 2536 2537 SwUndo * pUndo = new SwUndoFmtAttr(aOldSet, rFmt); 2538 2539 GetIDocumentUndoRedo().AppendUndo(pUndo); 2540 } 2541 2542 rFmt.SetFmtAttr(rSet); 2543 } 2544 2545 void SwDoc::RenameFmt(SwFmt & rFmt, const String & sNewName, 2546 sal_Bool bBroadcast) 2547 { 2548 SfxStyleFamily eFamily = SFX_STYLE_FAMILY_ALL; 2549 2550 if (GetIDocumentUndoRedo().DoesUndo()) 2551 { 2552 SwUndo * pUndo = NULL; 2553 2554 switch (rFmt.Which()) 2555 { 2556 case RES_CHRFMT: 2557 pUndo = new SwUndoRenameCharFmt(rFmt.GetName(), sNewName, this); 2558 eFamily = SFX_STYLE_FAMILY_PARA; 2559 break; 2560 case RES_TXTFMTCOLL: 2561 pUndo = new SwUndoRenameFmtColl(rFmt.GetName(), sNewName, this); 2562 eFamily = SFX_STYLE_FAMILY_CHAR; 2563 break; 2564 case RES_FRMFMT: 2565 pUndo = new SwUndoRenameFrmFmt(rFmt.GetName(), sNewName, this); 2566 eFamily = SFX_STYLE_FAMILY_FRAME; 2567 break; 2568 2569 default: 2570 break; 2571 } 2572 2573 if (pUndo) 2574 { 2575 GetIDocumentUndoRedo().AppendUndo(pUndo); 2576 } 2577 } 2578 2579 rFmt.SetName(sNewName); 2580 2581 if (bBroadcast) 2582 BroadcastStyleOperation(sNewName, eFamily, SFX_STYLESHEET_MODIFIED); 2583 } 2584 2585 // --> OD 2006-09-27 #i69627# 2586 namespace docfunc 2587 { 2588 bool HasOutlineStyleToBeWrittenAsNormalListStyle( SwDoc& rDoc ) 2589 { 2590 // If a parent paragraph style of one of the parargraph styles, which 2591 // are assigned to the list levels of the outline style, has a list style 2592 // set or inherits a list style from its parent style, the outline style 2593 // has to be written as a normal list style to the OpenDocument file 2594 // format or the OpenOffice.org file format. 2595 bool bRet( false ); 2596 2597 const SwTxtFmtColls* pTxtFmtColls( rDoc.GetTxtFmtColls() ); 2598 if ( pTxtFmtColls ) 2599 { 2600 const sal_uInt16 nCount = pTxtFmtColls->Count(); 2601 for ( sal_uInt16 i = 0; i < nCount; ++i ) 2602 { 2603 SwTxtFmtColl* pTxtFmtColl = (*pTxtFmtColls)[i]; 2604 2605 if ( pTxtFmtColl->IsDefault() || 2606 // pTxtFmtColl->GetOutlineLevel() == NO_NUMBERING ) //#outline level,zhaojianwei 2607 ! pTxtFmtColl->IsAssignedToListLevelOfOutlineStyle() ) //<-end,zhaojianwei 2608 { 2609 continue; 2610 } 2611 2612 const SwTxtFmtColl* pParentTxtFmtColl = 2613 dynamic_cast<const SwTxtFmtColl*>( pTxtFmtColl->DerivedFrom()); 2614 if ( !pParentTxtFmtColl ) 2615 continue; 2616 2617 if ( SFX_ITEM_SET == pParentTxtFmtColl->GetItemState( RES_PARATR_NUMRULE ) ) 2618 { 2619 // --> OD 2009-11-12 #i106218# 2620 // consider that the outline style is set 2621 const SwNumRuleItem& rDirectItem = pParentTxtFmtColl->GetNumRule(); 2622 if ( rDirectItem.GetValue() != rDoc.GetOutlineNumRule()->GetName() ) 2623 { 2624 bRet = true; 2625 break; 2626 } 2627 // <-- 2628 } 2629 } 2630 2631 } 2632 return bRet; 2633 } 2634 } 2635 // <-- 2636