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