/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include #include #include #include #include // fuer die UndoIds #include #include #include // MOVE SwUndoMove::SwUndoMove( const SwPaM& rRange, const SwPosition& rMvPos ) : SwUndo( UNDO_MOVE ), SwUndRng( rRange ), nMvDestNode( rMvPos.nNode.GetIndex() ), nMvDestCntnt( rMvPos.nContent.GetIndex() ), bMoveRedlines( false ) { bMoveRange = bJoinNext = bJoinPrev = sal_False; // StartNode vorm loeschen von Fussnoten besorgen! SwDoc* pDoc = rRange.GetDoc(); SwTxtNode* pTxtNd = pDoc->GetNodes()[ nSttNode ]->GetTxtNode(); SwTxtNode* pEndTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode(); pHistory = new SwHistory; if( pTxtNd ) { pHistory->Add( pTxtNd->GetTxtColl(), nSttNode, ND_TEXTNODE ); if ( pTxtNd->GetpSwpHints() ) { pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode, 0, pTxtNd->GetTxt().Len(), false ); } if( pTxtNd->HasSwAttrSet() ) pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode ); } if( pEndTxtNd && pEndTxtNd != pTxtNd ) { pHistory->Add( pEndTxtNd->GetTxtColl(), nEndNode, ND_TEXTNODE ); if ( pEndTxtNd->GetpSwpHints() ) { pHistory->CopyAttr( pEndTxtNd->GetpSwpHints(), nEndNode, 0, pEndTxtNd->GetTxt().Len(), false ); } if( pEndTxtNd->HasSwAttrSet() ) pHistory->CopyFmtAttr( *pEndTxtNd->GetpSwAttrSet(), nEndNode ); } pTxtNd = rMvPos.nNode.GetNode().GetTxtNode(); if (0 != pTxtNd) { pHistory->Add( pTxtNd->GetTxtColl(), nMvDestNode, ND_TEXTNODE ); if ( pTxtNd->GetpSwpHints() ) { pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nMvDestNode, 0, pTxtNd->GetTxt().Len(), false ); } if( pTxtNd->HasSwAttrSet() ) pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nMvDestNode ); } nFtnStt = pHistory->Count(); DelFtn( rRange ); if( pHistory && !pHistory->Count() ) DELETEZ( pHistory ); } SwUndoMove::SwUndoMove( SwDoc* pDoc, const SwNodeRange& rRg, const SwNodeIndex& rMvPos ) : SwUndo( UNDO_MOVE ), nMvDestNode( rMvPos.GetIndex() ), bMoveRedlines( false ) { bMoveRange = sal_True; bJoinNext = bJoinPrev = sal_False; nSttCntnt = nEndCntnt = nMvDestCntnt = STRING_MAXLEN; nSttNode = rRg.aStart.GetIndex(); nEndNode = rRg.aEnd.GetIndex(); // DelFtn( rRange ); // wird aus dem CntntBereich in den Sonderbereich verschoben ? sal_uLong nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex(); if( nMvDestNode < nCntntStt && rRg.aStart.GetIndex() > nCntntStt ) { // loesche alle Fussnoten. Diese sind dort nicht erwuenscht. SwPosition aPtPos( rRg.aEnd ); SwCntntNode* pCNd = rRg.aEnd.GetNode().GetCntntNode(); if( pCNd ) aPtPos.nContent.Assign( pCNd, pCNd->Len() ); SwPosition aMkPos( rRg.aStart ); if( 0 != ( pCNd = aMkPos.nNode.GetNode().GetCntntNode() )) aMkPos.nContent.Assign( pCNd, 0 ); DelCntntIndex( aMkPos, aPtPos, nsDelCntntType::DELCNT_FTN ); if( pHistory && !pHistory->Count() ) DELETEZ( pHistory ); } nFtnStt = 0; } void SwUndoMove::SetDestRange( const SwPaM& rRange, const SwPosition& rInsPos, sal_Bool bJoin, sal_Bool bCorrPam ) { const SwPosition *pStt = rRange.Start(), *pEnd = rRange.GetPoint() == pStt ? rRange.GetMark() : rRange.GetPoint(); nDestSttNode = pStt->nNode.GetIndex(); nDestSttCntnt = pStt->nContent.GetIndex(); nDestEndNode = pEnd->nNode.GetIndex(); nDestEndCntnt = pEnd->nContent.GetIndex(); nInsPosNode = rInsPos.nNode.GetIndex(); nInsPosCntnt = rInsPos.nContent.GetIndex(); if( bCorrPam ) { nDestSttNode--; nDestEndNode--; } bJoinNext = nDestSttNode != nDestEndNode && pStt->nNode.GetNode().GetTxtNode() && pEnd->nNode.GetNode().GetTxtNode(); bJoinPrev = bJoin; } void SwUndoMove::SetDestRange( const SwNodeIndex& rStt, const SwNodeIndex& rEnd, const SwNodeIndex& rInsPos ) { nDestSttNode = rStt.GetIndex(); nDestEndNode = rEnd.GetIndex(); if( nDestSttNode > nDestEndNode ) { nDestSttNode = nDestEndNode; nDestEndNode = rStt.GetIndex(); } nInsPosNode = rInsPos.GetIndex(); nDestSttCntnt = nDestEndCntnt = nInsPosCntnt = STRING_MAXLEN; } void SwUndoMove::UndoImpl(::sw::UndoRedoContext & rContext) { SwDoc *const pDoc = & rContext.GetDoc(); // Block, damit aus diesem gesprungen werden kann do { // erzeuge aus den Werten die Insert-Position und den Bereich SwNodeIndex aIdx( pDoc->GetNodes(), nDestSttNode ); if( bMoveRange ) { // nur ein Move mit SwRange SwNodeRange aRg( aIdx, aIdx ); aRg.aEnd = nDestEndNode; aIdx = nInsPosNode; bool bSuccess = pDoc->MoveNodeRange( aRg, aIdx, IDocumentContentOperations::DOC_MOVEDEFAULT ); if (!bSuccess) break; } else { SwPaM aPam( aIdx.GetNode(), nDestSttCntnt, *pDoc->GetNodes()[ nDestEndNode ], nDestEndCntnt ); // #i17764# if redlines are to be moved, we may not remove them before // pDoc->Move gets a chance to handle them if( ! bMoveRedlines ) RemoveIdxFromRange( aPam, sal_False ); SwPosition aPos( *pDoc->GetNodes()[ nInsPosNode] ); SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode(); aPos.nContent.Assign( pCNd, nInsPosCntnt ); if( pCNd->HasSwAttrSet() ) pCNd->ResetAllAttr(); if( pCNd->IsTxtNode() && ((SwTxtNode*)pCNd)->GetpSwpHints() ) ((SwTxtNode*)pCNd)->ClearSwpHintsArr( false ); // an der InsertPos erstmal alle Attribute entfernen, const bool bSuccess = pDoc->MoveRange( aPam, aPos, (bMoveRedlines) ? IDocumentContentOperations::DOC_MOVEREDLINES : IDocumentContentOperations::DOC_MOVEDEFAULT ); if (!bSuccess) break; aPam.Exchange(); aPam.DeleteMark(); // pDoc->ResetAttr( aPam, sal_False ); if( aPam.GetNode()->IsCntntNode() ) aPam.GetNode()->GetCntntNode()->ResetAllAttr(); // der Pam wird jetzt aufgegeben. } SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode(); if( bJoinNext ) { { RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx, SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) ); } // sind keine Pams mehr im naechsten TextNode pTxtNd->JoinNext(); } if( bJoinPrev && pTxtNd->CanJoinPrev( &aIdx ) ) { // ?? sind keine Pams mehr im naechsten TextNode ?? pTxtNd = aIdx.GetNode().GetTxtNode(); { RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx, SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) ); } pTxtNd->JoinNext(); } } while( sal_False ); if( pHistory ) { if( nFtnStt != pHistory->Count() ) pHistory->Rollback( pDoc, nFtnStt ); pHistory->TmpRollback( pDoc, 0 ); pHistory->SetTmpEnd( pHistory->Count() ); } // setze noch den Cursor auf den Undo-Bereich if( !bMoveRange ) { AddUndoRedoPaM(rContext); } } void SwUndoMove::RedoImpl(::sw::UndoRedoContext & rContext) { SwPaM *const pPam = & AddUndoRedoPaM(rContext); SwDoc & rDoc = rContext.GetDoc(); SwNodes& rNds = rDoc.GetNodes(); SwNodeIndex aIdx( rNds, nMvDestNode ); if( bMoveRange ) { // nur ein Move mit SwRange SwNodeRange aRg( rNds, nSttNode, rNds, nEndNode ); rDoc.MoveNodeRange( aRg, aIdx, (bMoveRedlines) ? IDocumentContentOperations::DOC_MOVEREDLINES : IDocumentContentOperations::DOC_MOVEDEFAULT ); } else { SwPaM aPam( *pPam->GetPoint() ); SetPaM( aPam ); SwPosition aMvPos( aIdx, SwIndex( aIdx.GetNode().GetCntntNode(), nMvDestCntnt )); DelFtn( aPam ); RemoveIdxFromRange( aPam, sal_False ); aIdx = aPam.Start()->nNode; sal_Bool bJoinTxt = aIdx.GetNode().IsTxtNode(); aIdx--; rDoc.MoveRange( aPam, aMvPos, IDocumentContentOperations::DOC_MOVEDEFAULT ); if( nSttNode != nEndNode && bJoinTxt ) { aIdx++; SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode(); if( pTxtNd && pTxtNd->CanJoinNext() ) { { RemoveIdxRel( aIdx.GetIndex() + 1, SwPosition( aIdx, SwIndex( pTxtNd, pTxtNd->GetTxt().Len() ) ) ); } pTxtNd->JoinNext(); } } *pPam->GetPoint() = *aPam.GetPoint(); pPam->SetMark(); *pPam->GetMark() = *aPam.GetMark(); } } void SwUndoMove::DelFtn( const SwPaM& rRange ) { // wird aus dem CntntBereich in den Sonderbereich verschoben ? SwDoc* pDoc = rRange.GetDoc(); sal_uLong nCntntStt = pDoc->GetNodes().GetEndOfAutotext().GetIndex(); if( nMvDestNode < nCntntStt && rRange.GetPoint()->nNode.GetIndex() >= nCntntStt ) { // loesche alle Fussnoten. Diese sind dort nicht erwuenscht. DelCntntIndex( *rRange.GetMark(), *rRange.GetPoint(), nsDelCntntType::DELCNT_FTN ); if( pHistory && !pHistory->Count() ) delete pHistory, pHistory = 0; } }