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