xref: /aoo41x/main/sw/source/core/undo/unspnd.cxx (revision cdf0e10c)
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