xref: /trunk/main/sw/source/core/undo/unspnd.cxx (revision efeef26f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <UndoSplitMove.hxx>
28 
29 #include "doc.hxx"
30 #include "pam.hxx"
31 #include "swtable.hxx"
32 #include "ndtxt.hxx"
33 #include "swundo.hxx"           // fuer die UndoIds
34 #include <editeng/brkitem.hxx>
35 #include <fmtpdsc.hxx>
36 #include <frmfmt.hxx>
37 #include <UndoCore.hxx>
38 #include "rolbck.hxx"
39 #include "redline.hxx"
40 #include "docary.hxx"
41 #include <IShellCursorSupplier.hxx>
42 
43 
44 //------------------------------------------------------------------
45 
46 // SPLITNODE
47 
48 
SwUndoSplitNode(SwDoc * pDoc,const SwPosition & rPos,sal_Bool bChkTable)49 SwUndoSplitNode::SwUndoSplitNode( SwDoc* pDoc, const SwPosition& rPos,
50 									sal_Bool bChkTable )
51 	: SwUndo( UNDO_SPLITNODE ), pHistory( 0 ), pRedlData( 0 ), nNode( rPos.nNode.GetIndex() ),
52 		nCntnt( rPos.nContent.GetIndex() ),
53 		bTblFlag( sal_False ), bChkTblStt( bChkTable )
54 {
55     SwTxtNode *const pTxtNd = rPos.nNode.GetNode().GetTxtNode();
56     OSL_ENSURE(pTxtNd, "SwUndoSplitNode: TextNode expected!");
57 	if( pTxtNd->GetpSwpHints() )
58 	{
59 		pHistory = new SwHistory;
60         pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nNode, 0,
61                             pTxtNd->GetTxt().Len(), false );
62 		if( !pHistory->Count() )
63 			DELETEZ( pHistory );
64 	}
65 	// Redline beachten
66 	if( pDoc->IsRedlineOn() )
67 	{
68 		pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT, pDoc->GetRedlineAuthor() );
69 		SetRedlineMode( pDoc->GetRedlineMode() );
70 	}
71 }
72 
~SwUndoSplitNode()73 SwUndoSplitNode::~SwUndoSplitNode()
74 {
75 	delete pHistory;
76 	delete pRedlData;
77 }
78 
UndoImpl(::sw::UndoRedoContext & rContext)79 void SwUndoSplitNode::UndoImpl(::sw::UndoRedoContext & rContext)
80 {
81     SwDoc *const pDoc = & rContext.GetDoc();
82     SwPaM & rPam( rContext.GetCursorSupplier().CreateNewShellCursor() );
83 	rPam.DeleteMark();
84 	if( bTblFlag )
85 	{
86 		// dann wurde direkt vor der akt. Tabelle ein TextNode eingefuegt.
87 		SwNodeIndex& rIdx = rPam.GetPoint()->nNode;
88 		rIdx = nNode;
89 		SwTxtNode* pTNd;
90 		SwNode* pCurrNd = pDoc->GetNodes()[ nNode + 1 ];
91 		SwTableNode* pTblNd = pCurrNd->FindTableNode();
92 		if( pCurrNd->IsCntntNode() && pTblNd &&
93 			0 != ( pTNd = pDoc->GetNodes()[ pTblNd->GetIndex()-1 ]->GetTxtNode() ))
94 		{
95 			// verschiebe die BreakAttribute noch
96 			SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
97 			const SfxItemSet* pNdSet = pTNd->GetpSwAttrSet();
98 			if( pNdSet )
99 			{
100 				const SfxPoolItem *pItem;
101 				if( SFX_ITEM_SET == pNdSet->GetItemState( RES_PAGEDESC, sal_False,
102 					&pItem ) )
103                     pTableFmt->SetFmtAttr( *pItem );
104 
105 				if( SFX_ITEM_SET == pNdSet->GetItemState( RES_BREAK, sal_False,
106 					 &pItem ) )
107                     pTableFmt->SetFmtAttr( *pItem );
108 			}
109 
110 			// dann loesche den wieder
111 			SwNodeIndex aDelNd( *pTblNd, -1 );
112 			rPam.GetPoint()->nContent.Assign( (SwCntntNode*)pCurrNd, 0 );
113 			RemoveIdxRel( aDelNd.GetIndex(), *rPam.GetPoint() );
114 			pDoc->GetNodes().Delete( aDelNd );
115 		}
116 	}
117 	else
118 	{
119 		SwTxtNode * pTNd = pDoc->GetNodes()[ nNode ]->GetTxtNode();
120 		if( pTNd )
121 		{
122 			rPam.GetPoint()->nNode = *pTNd;
123 			rPam.GetPoint()->nContent.Assign( pTNd, pTNd->GetTxt().Len() );
124 
125 			if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
126 			{
127 				rPam.SetMark();
128 				rPam.GetMark()->nNode++;
129 				rPam.GetMark()->nContent.Assign( rPam.GetMark()->
130 									nNode.GetNode().GetCntntNode(), 0 );
131 				pDoc->DeleteRedline( rPam, true, USHRT_MAX );
132 				rPam.DeleteMark();
133 			}
134 
135 			RemoveIdxRel( nNode+1, *rPam.GetPoint() );
136 
137 			pTNd->JoinNext();
138 			if( pHistory )
139 			{
140 				rPam.GetPoint()->nContent = 0;
141 				rPam.SetMark();
142 				rPam.GetPoint()->nContent = pTNd->GetTxt().Len();
143 
144                 pDoc->RstTxtAttrs( rPam, sal_True );
145                 pHistory->TmpRollback( pDoc, 0, false );
146             }
147         }
148     }
149 
150 	// setze noch den Cursor auf den Undo-Bereich
151 	rPam.DeleteMark();
152 	rPam.GetPoint()->nNode = nNode;
153 	rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), nCntnt );
154 }
155 
RedoImpl(::sw::UndoRedoContext & rContext)156 void SwUndoSplitNode::RedoImpl(::sw::UndoRedoContext & rContext)
157 {
158     SwPaM & rPam( rContext.GetCursorSupplier().CreateNewShellCursor() );
159 	rPam.GetPoint()->nNode = nNode;
160 	SwTxtNode * pTNd = rPam.GetNode()->GetTxtNode();
161     OSL_ENSURE(pTNd, "SwUndoSplitNode::RedoImpl(): SwTxtNode expected");
162     if (pTNd)
163 	{
164 		rPam.GetPoint()->nContent.Assign( pTNd, nCntnt );
165 
166 		SwDoc* pDoc = rPam.GetDoc();
167 		pDoc->SplitNode( *rPam.GetPoint(), bChkTblStt );
168 
169 		if( pHistory )
170 			pHistory->SetTmpEnd( pHistory->Count() );
171 
172 		if( ( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) ||
173 			( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) &&
174 				pDoc->GetRedlineTbl().Count() ))
175 		{
176 			rPam.SetMark();
177 			if( rPam.Move( fnMoveBackward ))
178 			{
179 				if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
180 				{
181 					RedlineMode_t eOld = pDoc->GetRedlineMode();
182 					pDoc->SetRedlineMode_intern((RedlineMode_t)(eOld & ~nsRedlineMode_t::REDLINE_IGNORE));
183 					pDoc->AppendRedline( new SwRedline( *pRedlData, rPam ), true);
184 					pDoc->SetRedlineMode_intern( eOld );
185 				}
186 				else
187 					pDoc->SplitRedline( rPam );
188 				rPam.Exchange();
189 			}
190 			rPam.DeleteMark();
191 		}
192 	}
193 }
194 
RepeatImpl(::sw::RepeatContext & rContext)195 void SwUndoSplitNode::RepeatImpl(::sw::RepeatContext & rContext)
196 {
197     rContext.GetDoc().SplitNode(
198         *rContext.GetRepeatPaM().GetPoint(), bChkTblStt );
199 }
200 
201