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 <UndoSplitMove.hxx> 32 33 #include "doc.hxx" 34 #include "pam.hxx" 35 #include "swtable.hxx" 36 #include "ndtxt.hxx" 37 #include "swundo.hxx" // fuer die UndoIds 38 #include <editeng/brkitem.hxx> 39 #include <fmtpdsc.hxx> 40 #include <frmfmt.hxx> 41 #include <UndoCore.hxx> 42 #include "rolbck.hxx" 43 #include "redline.hxx" 44 #include "docary.hxx" 45 #include <IShellCursorSupplier.hxx> 46 47 48 //------------------------------------------------------------------ 49 50 // SPLITNODE 51 52 53 SwUndoSplitNode::SwUndoSplitNode( SwDoc* pDoc, const SwPosition& rPos, 54 sal_Bool bChkTable ) 55 : SwUndo( UNDO_SPLITNODE ), pHistory( 0 ), pRedlData( 0 ), nNode( rPos.nNode.GetIndex() ), 56 nCntnt( rPos.nContent.GetIndex() ), 57 bTblFlag( sal_False ), bChkTblStt( bChkTable ) 58 { 59 SwTxtNode *const pTxtNd = rPos.nNode.GetNode().GetTxtNode(); 60 OSL_ENSURE(pTxtNd, "SwUndoSplitNode: TextNode expected!"); 61 if( pTxtNd->GetpSwpHints() ) 62 { 63 pHistory = new SwHistory; 64 pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nNode, 0, 65 pTxtNd->GetTxt().Len(), false ); 66 if( !pHistory->Count() ) 67 DELETEZ( pHistory ); 68 } 69 // Redline beachten 70 if( pDoc->IsRedlineOn() ) 71 { 72 pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT, pDoc->GetRedlineAuthor() ); 73 SetRedlineMode( pDoc->GetRedlineMode() ); 74 } 75 } 76 77 SwUndoSplitNode::~SwUndoSplitNode() 78 { 79 delete pHistory; 80 delete pRedlData; 81 } 82 83 void SwUndoSplitNode::UndoImpl(::sw::UndoRedoContext & rContext) 84 { 85 SwDoc *const pDoc = & rContext.GetDoc(); 86 SwPaM & rPam( rContext.GetCursorSupplier().CreateNewShellCursor() ); 87 rPam.DeleteMark(); 88 if( bTblFlag ) 89 { 90 // dann wurde direkt vor der akt. Tabelle ein TextNode eingefuegt. 91 SwNodeIndex& rIdx = rPam.GetPoint()->nNode; 92 rIdx = nNode; 93 SwTxtNode* pTNd; 94 SwNode* pCurrNd = pDoc->GetNodes()[ nNode + 1 ]; 95 SwTableNode* pTblNd = pCurrNd->FindTableNode(); 96 if( pCurrNd->IsCntntNode() && pTblNd && 97 0 != ( pTNd = pDoc->GetNodes()[ pTblNd->GetIndex()-1 ]->GetTxtNode() )) 98 { 99 // verschiebe die BreakAttribute noch 100 SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt(); 101 const SfxItemSet* pNdSet = pTNd->GetpSwAttrSet(); 102 if( pNdSet ) 103 { 104 const SfxPoolItem *pItem; 105 if( SFX_ITEM_SET == pNdSet->GetItemState( RES_PAGEDESC, sal_False, 106 &pItem ) ) 107 pTableFmt->SetFmtAttr( *pItem ); 108 109 if( SFX_ITEM_SET == pNdSet->GetItemState( RES_BREAK, sal_False, 110 &pItem ) ) 111 pTableFmt->SetFmtAttr( *pItem ); 112 } 113 114 // dann loesche den wieder 115 SwNodeIndex aDelNd( *pTblNd, -1 ); 116 rPam.GetPoint()->nContent.Assign( (SwCntntNode*)pCurrNd, 0 ); 117 RemoveIdxRel( aDelNd.GetIndex(), *rPam.GetPoint() ); 118 pDoc->GetNodes().Delete( aDelNd ); 119 } 120 } 121 else 122 { 123 SwTxtNode * pTNd = pDoc->GetNodes()[ nNode ]->GetTxtNode(); 124 if( pTNd ) 125 { 126 rPam.GetPoint()->nNode = *pTNd; 127 rPam.GetPoint()->nContent.Assign( pTNd, pTNd->GetTxt().Len() ); 128 129 if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) 130 { 131 rPam.SetMark(); 132 rPam.GetMark()->nNode++; 133 rPam.GetMark()->nContent.Assign( rPam.GetMark()-> 134 nNode.GetNode().GetCntntNode(), 0 ); 135 pDoc->DeleteRedline( rPam, true, USHRT_MAX ); 136 rPam.DeleteMark(); 137 } 138 139 RemoveIdxRel( nNode+1, *rPam.GetPoint() ); 140 141 pTNd->JoinNext(); 142 if( pHistory ) 143 { 144 rPam.GetPoint()->nContent = 0; 145 rPam.SetMark(); 146 rPam.GetPoint()->nContent = pTNd->GetTxt().Len(); 147 148 pDoc->RstTxtAttrs( rPam, sal_True ); 149 pHistory->TmpRollback( pDoc, 0, false ); 150 } 151 } 152 } 153 154 // setze noch den Cursor auf den Undo-Bereich 155 rPam.DeleteMark(); 156 rPam.GetPoint()->nNode = nNode; 157 rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), nCntnt ); 158 } 159 160 void SwUndoSplitNode::RedoImpl(::sw::UndoRedoContext & rContext) 161 { 162 SwPaM & rPam( rContext.GetCursorSupplier().CreateNewShellCursor() ); 163 rPam.GetPoint()->nNode = nNode; 164 SwTxtNode * pTNd = rPam.GetNode()->GetTxtNode(); 165 OSL_ENSURE(pTNd, "SwUndoSplitNode::RedoImpl(): SwTxtNode expected"); 166 if (pTNd) 167 { 168 rPam.GetPoint()->nContent.Assign( pTNd, nCntnt ); 169 170 SwDoc* pDoc = rPam.GetDoc(); 171 pDoc->SplitNode( *rPam.GetPoint(), bChkTblStt ); 172 173 if( pHistory ) 174 pHistory->SetTmpEnd( pHistory->Count() ); 175 176 if( ( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) || 177 ( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) && 178 pDoc->GetRedlineTbl().Count() )) 179 { 180 rPam.SetMark(); 181 if( rPam.Move( fnMoveBackward )) 182 { 183 if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) 184 { 185 RedlineMode_t eOld = pDoc->GetRedlineMode(); 186 pDoc->SetRedlineMode_intern((RedlineMode_t)(eOld & ~nsRedlineMode_t::REDLINE_IGNORE)); 187 pDoc->AppendRedline( new SwRedline( *pRedlData, rPam ), true); 188 pDoc->SetRedlineMode_intern( eOld ); 189 } 190 else 191 pDoc->SplitRedline( rPam ); 192 rPam.Exchange(); 193 } 194 rPam.DeleteMark(); 195 } 196 } 197 } 198 199 void SwUndoSplitNode::RepeatImpl(::sw::RepeatContext & rContext) 200 { 201 rContext.GetDoc().SplitNode( 202 *rContext.GetRepeatPaM().GetPoint(), bChkTblStt ); 203 } 204 205