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 #include <UndoNumbering.hxx> 28 29 #include <hintids.hxx> 30 #include <editeng/lrspitem.hxx> 31 #include <doc.hxx> 32 #include <IDocumentUndoRedo.hxx> 33 #include <swundo.hxx> // fuer die UndoIds 34 #include <pam.hxx> 35 #include <ndtxt.hxx> 36 #include <UndoCore.hxx> 37 #include <rolbck.hxx> 38 39 40 SV_DECL_PTRARR_DEL( _SfxPoolItems, SfxPoolItem*, 16, 16 ) 41 SV_IMPL_PTRARR( _SfxPoolItems, SfxPoolItem* ); 42 43 44 SwUndoInsNum::SwUndoInsNum( const SwNumRule& rOldRule, 45 const SwNumRule& rNewRule, 46 SwUndoId nUndoId ) 47 : SwUndo( nUndoId ), 48 aNumRule( rNewRule ), pHistory( 0 ), nSttSet( ULONG_MAX ), 49 pOldNumRule( new SwNumRule( rOldRule )), nLRSavePos( 0 ) 50 { 51 } 52 53 SwUndoInsNum::SwUndoInsNum( const SwPaM& rPam, const SwNumRule& rRule ) 54 : SwUndo( UNDO_INSNUM ), SwUndRng( rPam ), 55 aNumRule( rRule ), pHistory( 0 ), 56 nSttSet( ULONG_MAX ), pOldNumRule( 0 ), nLRSavePos( 0 ) 57 { 58 } 59 60 SwUndoInsNum::SwUndoInsNum( const SwPosition& rPos, const SwNumRule& rRule, 61 const String& rReplaceRule ) 62 : SwUndo( UNDO_INSNUM ), 63 aNumRule( rRule ), pHistory( 0 ), 64 nSttSet( ULONG_MAX ), pOldNumRule( 0 ), 65 sReplaceRule( rReplaceRule ), nLRSavePos( 0 ) 66 { 67 // keine Selektion !! 68 nEndNode = 0, nEndCntnt = USHRT_MAX; 69 nSttNode = rPos.nNode.GetIndex(); 70 nSttCntnt = rPos.nContent.GetIndex(); 71 } 72 73 SwUndoInsNum::~SwUndoInsNum() 74 { 75 delete pHistory; 76 delete pOldNumRule; 77 } 78 79 SwRewriter SwUndoInsNum::GetRewriter() const 80 { 81 SwRewriter aResult; 82 if( UNDO_INSFMTATTR == GetId() ) 83 aResult.AddRule(UNDO_ARG1, aNumRule.GetName()); 84 return aResult; 85 } 86 87 void SwUndoInsNum::UndoImpl(::sw::UndoRedoContext & rContext) 88 { 89 SwDoc & rDoc = rContext.GetDoc(); 90 91 if( pOldNumRule ) 92 rDoc.ChgNumRuleFmts( *pOldNumRule ); 93 94 if( pHistory ) 95 { 96 SwTxtNode* pNd; 97 if( ULONG_MAX != nSttSet && 98 0 != ( pNd = rDoc.GetNodes()[ nSttSet ]->GetTxtNode() )) 99 pNd->SetListRestart( sal_True ); 100 else 101 pNd = 0; 102 103 104 if( nLRSavePos ) 105 { 106 // sofort Updaten, damit eventuell "alte" LRSpaces wieder 107 // gueltig werden. 108 // !!! Dafuer suche aber erstmal den richtigen NumRule - Namen! 109 if( !pNd && nSttNode ) 110 pNd = rDoc.GetNodes()[ nSttNode ]->GetTxtNode(); 111 112 // This code seems to be superfluous because the methods 113 // don't have any known side effects. 114 // ToDo: iasue i83806 should be used to remove this code 115 const SwNumRule* pNdRule; 116 if( pNd ) 117 pNdRule = pNd->GetNumRule(); 118 else 119 pNdRule = rDoc.FindNumRulePtr( aNumRule.GetName() ); 120 // End of ToDo for issue i83806 121 122 pHistory->TmpRollback( &rDoc, nLRSavePos ); 123 124 } 125 pHistory->TmpRollback( &rDoc, 0 ); 126 pHistory->SetTmpEnd( pHistory->Count() ); 127 } 128 129 if (nSttNode) 130 { 131 AddUndoRedoPaM(rContext); 132 } 133 } 134 135 void SwUndoInsNum::RedoImpl(::sw::UndoRedoContext & rContext) 136 { 137 SwDoc & rDoc = rContext.GetDoc(); 138 139 if ( pOldNumRule ) 140 rDoc.ChgNumRuleFmts( aNumRule ); 141 else if ( pHistory ) 142 { 143 SwPaM & rPam( AddUndoRedoPaM( rContext ) ); 144 if ( sReplaceRule.Len() ) 145 { 146 rDoc.ReplaceNumRule( *rPam.GetPoint(), sReplaceRule, aNumRule.GetName() ); 147 } 148 else 149 { 150 rDoc.SetNumRule( rPam, aNumRule, false ); 151 } 152 } 153 } 154 155 void SwUndoInsNum::SetLRSpaceEndPos() 156 { 157 if( pHistory ) 158 nLRSavePos = pHistory->Count(); 159 } 160 161 void SwUndoInsNum::RepeatImpl(::sw::RepeatContext & rContext) 162 { 163 SwDoc & rDoc( rContext.GetDoc() ); 164 if ( nSttNode ) 165 { 166 if ( !sReplaceRule.Len() ) 167 { 168 rDoc.SetNumRule( rContext.GetRepeatPaM(), aNumRule, false ); 169 } 170 } 171 else 172 { 173 rDoc.ChgNumRuleFmts( aNumRule ); 174 } 175 } 176 177 SwHistory* SwUndoInsNum::GetHistory() 178 { 179 if( !pHistory ) 180 pHistory = new SwHistory; 181 return pHistory; 182 } 183 184 void SwUndoInsNum::SaveOldNumRule( const SwNumRule& rOld ) 185 { 186 if( !pOldNumRule ) 187 pOldNumRule = new SwNumRule( rOld ); 188 } 189 190 /* */ 191 192 193 SwUndoDelNum::SwUndoDelNum( const SwPaM& rPam ) 194 : SwUndo( UNDO_DELNUM ), SwUndRng( rPam ), 195 aNodeIdx( sal_uInt8( nEndNode - nSttNode > 255 ? 255 : nEndNode - nSttNode )) 196 { 197 pHistory = new SwHistory; 198 } 199 200 SwUndoDelNum::~SwUndoDelNum() 201 { 202 delete pHistory; 203 } 204 205 void SwUndoDelNum::UndoImpl(::sw::UndoRedoContext & rContext) 206 { 207 SwDoc & rDoc = rContext.GetDoc(); 208 209 pHistory->TmpRollback( &rDoc, 0 ); 210 pHistory->SetTmpEnd( pHistory->Count() ); 211 212 for( sal_uInt16 n = 0; n < aNodeIdx.Count(); ++n ) 213 { 214 SwTxtNode* pNd = rDoc.GetNodes()[ aNodeIdx[ n ] ]->GetTxtNode(); 215 ASSERT( pNd, "Where is TextNode gone?" ); 216 pNd->SetAttrListLevel(aLevels[ n ] ); 217 218 if( pNd->GetCondFmtColl() ) 219 pNd->ChkCondColl(); 220 } 221 222 AddUndoRedoPaM(rContext); 223 } 224 225 void SwUndoDelNum::RedoImpl(::sw::UndoRedoContext & rContext) 226 { 227 SwPaM & rPam( AddUndoRedoPaM(rContext) ); 228 rContext.GetDoc().DelNumRules(rPam); 229 } 230 231 void SwUndoDelNum::RepeatImpl(::sw::RepeatContext & rContext) 232 { 233 rContext.GetDoc().DelNumRules(rContext.GetRepeatPaM()); 234 } 235 236 void SwUndoDelNum::AddNode( const SwTxtNode& rNd, sal_Bool ) 237 { 238 if( rNd.GetNumRule() ) 239 { 240 sal_uInt16 nIns = aNodeIdx.Count(); 241 aNodeIdx.Insert( rNd.GetIndex(), nIns ); 242 243 aLevels.insert( aLevels.begin() + nIns, static_cast<sal_uInt8>(rNd.GetActualListLevel()) ); 244 } 245 } 246 247 248 /* */ 249 250 251 SwUndoMoveNum::SwUndoMoveNum( const SwPaM& rPam, long nOff, sal_Bool bIsOutlMv ) 252 : SwUndo( bIsOutlMv ? UNDO_OUTLINE_UD : UNDO_MOVENUM ), 253 SwUndRng( rPam ), 254 nNewStt( 0 ), nOffset( nOff ) 255 { 256 // nOffset: nach unten => 1 257 // nach oben => -1 258 } 259 260 void SwUndoMoveNum::UndoImpl(::sw::UndoRedoContext & rContext) 261 { 262 sal_uLong nTmpStt = nSttNode, nTmpEnd = nEndNode; 263 264 if( nEndNode || USHRT_MAX != nEndCntnt ) // Bereich ? 265 { 266 if( nNewStt < nSttNode ) // nach vorne verschoben 267 nEndNode = nEndNode - ( nSttNode - nNewStt ); 268 else 269 nEndNode = nEndNode + ( nNewStt - nSttNode ); 270 } 271 nSttNode = nNewStt; 272 273 //JP 22.06.95: wird wollen die Bookmarks/Verzeichnisse behalten, oder? 274 // SetPaM( rUndoIter ); 275 // RemoveIdxFromRange( *rUndoIter.pAktPam, sal_True ); 276 277 SwPaM & rPam( AddUndoRedoPaM(rContext) ); 278 rContext.GetDoc().MoveParagraph( rPam, -nOffset, 279 UNDO_OUTLINE_UD == GetId() ); 280 nSttNode = nTmpStt; 281 nEndNode = nTmpEnd; 282 } 283 284 void SwUndoMoveNum::RedoImpl(::sw::UndoRedoContext & rContext) 285 { 286 //JP 22.06.95: wird wollen die Bookmarks/Verzeichnisse behalten, oder? 287 // SetPaM( rUndoIter ); 288 // RemoveIdxFromRange( *rUndoIter.pAktPam, sal_True ); 289 290 SwPaM & rPam( AddUndoRedoPaM(rContext) ); 291 rContext.GetDoc().MoveParagraph(rPam, nOffset, UNDO_OUTLINE_UD == GetId()); 292 } 293 294 void SwUndoMoveNum::RepeatImpl(::sw::RepeatContext & rContext) 295 { 296 SwDoc & rDoc = rContext.GetDoc(); 297 if( UNDO_OUTLINE_UD == GetId() ) 298 { 299 rDoc.MoveOutlinePara(rContext.GetRepeatPaM(), 300 0 < nOffset ? 1 : -1 ); 301 } 302 else 303 { 304 rDoc.MoveParagraph(rContext.GetRepeatPaM(), nOffset, sal_False); 305 } 306 } 307 308 /* */ 309 310 311 SwUndoNumUpDown::SwUndoNumUpDown( const SwPaM& rPam, short nOff ) 312 : SwUndo( nOff > 0 ? UNDO_NUMUP : UNDO_NUMDOWN ), SwUndRng( rPam ), 313 nOffset( nOff ) 314 { 315 // nOffset: Down => 1 316 // Up => -1 317 } 318 319 void SwUndoNumUpDown::UndoImpl(::sw::UndoRedoContext & rContext) 320 { 321 SwPaM & rPam( AddUndoRedoPaM(rContext) ); 322 rContext.GetDoc().NumUpDown(rPam, 1 != nOffset ); 323 } 324 325 void SwUndoNumUpDown::RedoImpl(::sw::UndoRedoContext & rContext) 326 { 327 SwPaM & rPam( AddUndoRedoPaM(rContext) ); 328 rContext.GetDoc().NumUpDown(rPam, 1 == nOffset); 329 } 330 331 void SwUndoNumUpDown::RepeatImpl(::sw::RepeatContext & rContext) 332 { 333 rContext.GetDoc().NumUpDown(rContext.GetRepeatPaM(), 1 == nOffset); 334 } 335 336 /* */ 337 338 // #115901# 339 SwUndoNumOrNoNum::SwUndoNumOrNoNum( const SwNodeIndex& rIdx, sal_Bool bOldNum, 340 sal_Bool bNewNum) 341 : SwUndo( UNDO_NUMORNONUM ), nIdx( rIdx.GetIndex() ), mbNewNum(bNewNum), 342 mbOldNum(bOldNum) 343 { 344 } 345 346 // #115901#, #i40034# 347 void SwUndoNumOrNoNum::UndoImpl(::sw::UndoRedoContext & rContext) 348 { 349 SwNodeIndex aIdx( rContext.GetDoc().GetNodes(), nIdx ); 350 SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode(); 351 352 if (NULL != pTxtNd) 353 { 354 pTxtNd->SetCountedInList(mbOldNum); 355 } 356 } 357 358 // #115901#, #i40034# 359 void SwUndoNumOrNoNum::RedoImpl(::sw::UndoRedoContext & rContext) 360 { 361 SwNodeIndex aIdx( rContext.GetDoc().GetNodes(), nIdx ); 362 SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode(); 363 364 if (NULL != pTxtNd) 365 { 366 pTxtNd->SetCountedInList(mbNewNum); 367 } 368 } 369 370 // #115901# 371 void SwUndoNumOrNoNum::RepeatImpl(::sw::RepeatContext & rContext) 372 { 373 SwDoc & rDoc = rContext.GetDoc(); 374 if (mbOldNum && ! mbNewNum) 375 { 376 rDoc.NumOrNoNum(rContext.GetRepeatPaM().GetPoint()->nNode, sal_False); 377 } 378 else if ( ! mbOldNum && mbNewNum ) 379 { 380 rDoc.NumOrNoNum(rContext.GetRepeatPaM().GetPoint()->nNode, sal_True); 381 } 382 } 383 384 /* */ 385 386 SwUndoNumRuleStart::SwUndoNumRuleStart( const SwPosition& rPos, sal_Bool bFlg ) 387 : SwUndo( UNDO_SETNUMRULESTART ), 388 nIdx( rPos.nNode.GetIndex() ), nOldStt( USHRT_MAX ), 389 nNewStt( USHRT_MAX ), bSetSttValue( sal_False ), bFlag( bFlg ) 390 { 391 } 392 393 SwUndoNumRuleStart::SwUndoNumRuleStart( const SwPosition& rPos, sal_uInt16 nStt ) 394 : SwUndo( UNDO_SETNUMRULESTART ), 395 nIdx( rPos.nNode.GetIndex() ), 396 nOldStt( USHRT_MAX ), nNewStt( nStt ), bSetSttValue( sal_True ) 397 { 398 SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode(); 399 if ( pTxtNd ) 400 { 401 // --> OD 2008-02-28 #refactorlists# 402 if ( pTxtNd->HasAttrListRestartValue() ) 403 { 404 nOldStt = static_cast<sal_uInt16>(pTxtNd->GetAttrListRestartValue()); 405 } 406 else 407 { 408 nOldStt = USHRT_MAX; // indicating, that the list restart value is not set 409 } 410 // <-- 411 } 412 } 413 414 415 void SwUndoNumRuleStart::UndoImpl(::sw::UndoRedoContext & rContext) 416 { 417 SwDoc & rDoc = rContext.GetDoc(); 418 SwPosition const aPos( *rDoc.GetNodes()[ nIdx ] ); 419 if( bSetSttValue ) 420 { 421 rDoc.SetNodeNumStart( aPos, nOldStt ); 422 } 423 else 424 { 425 rDoc.SetNumRuleStart( aPos, !bFlag ); 426 } 427 } 428 429 430 void SwUndoNumRuleStart::RedoImpl(::sw::UndoRedoContext & rContext) 431 { 432 SwDoc & rDoc = rContext.GetDoc(); 433 SwPosition const aPos( *rDoc.GetNodes()[ nIdx ] ); 434 if( bSetSttValue ) 435 { 436 rDoc.SetNodeNumStart( aPos, nNewStt ); 437 } 438 else 439 { 440 rDoc.SetNumRuleStart( aPos, bFlag ); 441 } 442 } 443 444 445 void SwUndoNumRuleStart::RepeatImpl(::sw::RepeatContext & rContext) 446 { 447 SwDoc & rDoc = rContext.GetDoc(); 448 if( bSetSttValue ) 449 { 450 rDoc.SetNodeNumStart(*rContext.GetRepeatPaM().GetPoint(), nNewStt); 451 } 452 else 453 { 454 rDoc.SetNumRuleStart(*rContext.GetRepeatPaM().GetPoint(), bFlag); 455 } 456 } 457 458 459