/************************************************************** * * 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 #include #include #include // fuer die UndoIds #include #include #include #include #include SwUndoInserts::SwUndoInserts( SwUndoId nUndoId, const SwPaM& rPam ) : SwUndo( nUndoId ), SwUndRng( rPam ), pTxtFmtColl( 0 ), pLastNdColl(0), pFrmFmts( 0 ), pRedlData( 0 ), bSttWasTxtNd( sal_True ), nNdDiff( 0 ), pPos( 0 ), nSetPos( 0 ) { pHistory = new SwHistory; SwDoc* pDoc = (SwDoc*)rPam.GetDoc(); SwTxtNode* pTxtNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode(); if( pTxtNd ) { pTxtFmtColl = pTxtNd->GetTxtColl(); pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode, 0, pTxtNd->GetTxt().Len(), false ); if( pTxtNd->HasSwAttrSet() ) pHistory->CopyFmtAttr( *pTxtNd->GetpSwAttrSet(), nSttNode ); if( !nSttCntnt ) // dann werden Flys mitgenommen !! { sal_uInt16 nArrLen = pDoc->GetSpzFrmFmts()->Count(); for( sal_uInt16 n = 0; n < nArrLen; ++n ) { SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[n]; SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor(); const SwPosition* pAPos = pAnchor->GetCntntAnchor(); if (pAPos && (pAnchor->GetAnchorId() == FLY_AT_PARA) && nSttNode == pAPos->nNode.GetIndex() ) { if( !pFrmFmts ) pFrmFmts = new SvPtrarr; pFrmFmts->Insert( pFmt, pFrmFmts->Count() ); } } } } // Redline beachten if( pDoc->IsRedlineOn() ) { pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT, pDoc->GetRedlineAuthor() ); SetRedlineMode( pDoc->GetRedlineMode() ); } } // setze den Destination-Bereich nach dem Einlesen. void SwUndoInserts::SetInsertRange( const SwPaM& rPam, sal_Bool bScanFlys, sal_Bool bSttIsTxtNd ) { const SwPosition* pTmpPos = rPam.End(); nEndNode = pTmpPos->nNode.GetIndex(); nEndCntnt = pTmpPos->nContent.GetIndex(); if( rPam.HasMark() ) { if( pTmpPos == rPam.GetPoint() ) pTmpPos = rPam.GetMark(); else pTmpPos = rPam.GetPoint(); nSttNode = pTmpPos->nNode.GetIndex(); nSttCntnt = pTmpPos->nContent.GetIndex(); if( !bSttIsTxtNd ) // wird eine Tabellenselektion eingefuegt, { ++nSttNode; // dann stimmt der CopyPam nicht ganz bSttWasTxtNd = sal_False; } } if( bScanFlys && !nSttCntnt ) { // dann alle neuen Flys zusammen sammeln !! SwDoc* pDoc = (SwDoc*)rPam.GetDoc(); sal_uInt16 nFndPos, nArrLen = pDoc->GetSpzFrmFmts()->Count(); for( sal_uInt16 n = 0; n < nArrLen; ++n ) { SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[n]; SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor(); SwPosition const*const pAPos = pAnchor->GetCntntAnchor(); if (pAPos && (pAnchor->GetAnchorId() == FLY_AT_PARA) && nSttNode == pAPos->nNode.GetIndex() ) { if( !pFrmFmts || USHRT_MAX == ( nFndPos = pFrmFmts->GetPos( pFmt ) ) ) { ::boost::shared_ptr const pFlyUndo( new SwUndoInsLayFmt(pFmt, 0, 0)); m_FlyUndos.push_back(pFlyUndo); } else pFrmFmts->Remove( nFndPos ); } } delete pFrmFmts, pFrmFmts = 0; } } SwUndoInserts::~SwUndoInserts() { if( pPos ) // loesche noch den Bereich aus dem UndoNodes Array { // Insert speichert den Inhalt in der IconSection SwNodes& rUNds = pPos->nNode.GetNodes(); if( pPos->nContent.GetIndex() ) // nicht den gesamten Node loeschen { SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode(); ASSERT( pTxtNd, "kein TextNode, aus dem geloescht werden soll" ); if( pTxtNd ) // Robust { pTxtNd->EraseText( pPos->nContent ); } pPos->nNode++; } pPos->nContent.Assign( 0, 0 ); rUNds.Delete( pPos->nNode, rUNds.GetEndOfExtras().GetIndex() - pPos->nNode.GetIndex() ); delete pPos; } delete pFrmFmts; delete pRedlData; } void SwUndoInserts::UndoImpl(::sw::UndoRedoContext & rContext) { SwDoc *const pDoc = & rContext.GetDoc(); SwPaM *const pPam = & AddUndoRedoPaM(rContext); if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) pDoc->DeleteRedline( *pPam, true, USHRT_MAX ); // sind an Point/Mark 2 unterschiedliche TextNodes, dann muss ein // JoinNext ausgefuehrt werden. sal_Bool bJoinNext = nSttNode != nEndNode && pPam->GetMark()->nNode.GetNode().GetTxtNode() && pPam->GetPoint()->nNode.GetNode().GetTxtNode(); // gibts ueberhaupt Inhalt ? (laden von Zeichenvorlagen hat kein Inhalt!) if( nSttNode != nEndNode || nSttCntnt != nEndCntnt ) { if( nSttNode != nEndNode ) { SwTxtNode* pTxtNd = pDoc->GetNodes()[ nEndNode ]->GetTxtNode(); if( pTxtNd && pTxtNd->GetTxt().Len() == nEndCntnt ) pLastNdColl = pTxtNd->GetTxtColl(); } RemoveIdxFromRange( *pPam, sal_False ); SetPaM(*pPam); // sind Fussnoten oder CntntFlyFrames im Text ?? nSetPos = pHistory->Count(); nNdDiff = pPam->GetMark()->nNode.GetIndex(); DelCntntIndex( *pPam->GetMark(), *pPam->GetPoint() ); nNdDiff -= pPam->GetMark()->nNode.GetIndex(); if( *pPam->GetPoint() != *pPam->GetMark() ) { pPos = new SwPosition( *pPam->GetPoint() ); MoveToUndoNds( *pPam, &pPos->nNode, &pPos->nContent ); if( !bSttWasTxtNd ) pPam->Move( fnMoveBackward, fnGoCntnt ); } } if (m_FlyUndos.size()) { sal_uLong nTmp = pPam->GetPoint()->nNode.GetIndex(); for (size_t n = m_FlyUndos.size(); 0 < n; --n) { m_FlyUndos[ n-1 ]->UndoImpl(rContext); } nNdDiff += nTmp - pPam->GetPoint()->nNode.GetIndex(); } SwNodeIndex& rIdx = pPam->GetPoint()->nNode; SwTxtNode* pTxtNode = rIdx.GetNode().GetTxtNode(); if( pTxtNode ) { if( !pTxtFmtColl ) // falls 0, dann war hier auch kein TextNode, { // dann muss dieser geloescht werden, SwNodeIndex aDelIdx( rIdx ); rIdx++; SwCntntNode* pCNd = rIdx.GetNode().GetCntntNode(); xub_StrLen nCnt = 0; if( pCNd ) nCnt = pCNd->Len(); pPam->GetPoint()->nContent.Assign( pCNd, nCnt ); pPam->SetMark(); pPam->DeleteMark(); RemoveIdxRel( aDelIdx.GetIndex(), *pPam->GetPoint() ); pDoc->GetNodes().Delete( aDelIdx, 1 ); } else { if( bJoinNext && pTxtNode->CanJoinNext()) { { RemoveIdxRel( rIdx.GetIndex()+1, SwPosition( rIdx, SwIndex( pTxtNode, pTxtNode->GetTxt().Len() ))); } pTxtNode->JoinNext(); } // reset all text attributes in the paragraph! pTxtNode->RstTxtAttr( SwIndex(pTxtNode, 0), pTxtNode->Len(), 0, 0, true ); // setze alle Attribute im Node zurueck pTxtNode->ResetAllAttr(); if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pTxtFmtColl )) pTxtFmtColl = (SwTxtFmtColl*)pTxtNode->ChgFmtColl( pTxtFmtColl ); pHistory->SetTmpEnd( nSetPos ); pHistory->TmpRollback( pDoc, 0, false ); } } } void SwUndoInserts::RedoImpl(::sw::UndoRedoContext & rContext) { // setze noch den Cursor auf den Redo-Bereich SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor()); SwDoc* pDoc = pPam->GetDoc(); pPam->DeleteMark(); pPam->GetPoint()->nNode = nSttNode - nNdDiff; SwCntntNode* pCNd = pPam->GetCntntNode(); pPam->GetPoint()->nContent.Assign( pCNd, nSttCntnt ); SwTxtFmtColl* pSavTxtFmtColl = pTxtFmtColl; if( pTxtFmtColl && pCNd && pCNd->IsTxtNode() ) pSavTxtFmtColl = ((SwTxtNode*)pCNd)->GetTxtColl(); pHistory->SetTmpEnd( nSetPos ); // alte Anfangs-Position fuers Rollback zurueckholen if( ( nSttNode != nEndNode || nSttCntnt != nEndCntnt ) && pPos ) { sal_Bool bMvBkwrd = MovePtBackward( *pPam ); // Inhalt wieder einfuegen. (erst pPos abmelden !!) sal_uLong nMvNd = pPos->nNode.GetIndex(); xub_StrLen nMvCnt = pPos->nContent.GetIndex(); DELETEZ( pPos ); MoveFromUndoNds( *pDoc, nMvNd, nMvCnt, *pPam->GetMark() ); if( bSttWasTxtNd ) MovePtForward( *pPam, bMvBkwrd ); pPam->Exchange(); } if( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pTxtFmtColl )) { SwTxtNode* pTxtNd = pPam->GetMark()->nNode.GetNode().GetTxtNode(); if( pTxtNd ) pTxtNd->ChgFmtColl( pTxtFmtColl ); } pTxtFmtColl = pSavTxtFmtColl; if( pLastNdColl && USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos( pLastNdColl ) && pPam->GetPoint()->nNode != pPam->GetMark()->nNode ) { SwTxtNode* pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode(); if( pTxtNd ) pTxtNd->ChgFmtColl( pLastNdColl ); } for (size_t n = m_FlyUndos.size(); 0 < n; --n) { m_FlyUndos[ n-1 ]->RedoImpl(rContext); } pHistory->Rollback( pDoc, nSetPos ); if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) { RedlineMode_t eOld = pDoc->GetRedlineMode(); pDoc->SetRedlineMode_intern((RedlineMode_t)( eOld & ~nsRedlineMode_t::REDLINE_IGNORE )); pDoc->AppendRedline( new SwRedline( *pRedlData, *pPam ), true); pDoc->SetRedlineMode_intern( eOld ); } else if( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) && pDoc->GetRedlineTbl().Count() ) pDoc->SplitRedline( *pPam ); } void SwUndoInserts::RepeatImpl(::sw::RepeatContext & rContext) { SwPaM aPam( rContext.GetDoc().GetNodes().GetEndOfContent() ); SetPaM( aPam ); SwPaM & rRepeatPaM( rContext.GetRepeatPaM() ); aPam.GetDoc()->CopyRange( aPam, *rRepeatPaM.GetPoint(), false ); } ////////////////////////////////////////////////////////////////////////// SwUndoInsDoc::SwUndoInsDoc( const SwPaM& rPam ) : SwUndoInserts( UNDO_INSDOKUMENT, rPam ) { } SwUndoCpyDoc::SwUndoCpyDoc( const SwPaM& rPam ) : SwUndoInserts( UNDO_COPY, rPam ) { }