1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <UndoSplitMove.hxx>
25 #include <UndoCore.hxx>
29 SwUndoMove::SwUndoMove( const SwPaM
& rRange
, const SwPosition
& rMvPos
)
30 : SwUndo( SwUndoId::MOVE
, &rRange
.GetDoc() )
35 , m_nMoveDestNode(rMvPos
.GetNodeIndex())
36 , m_nDestStartContent(0)
37 , m_nDestEndContent(0)
39 , m_nMoveDestContent(rMvPos
.GetContentIndex())
42 , m_bMoveRedlines(false)
44 // get StartNode from footnotes before delete!
45 SwDoc
& rDoc
= rRange
.GetDoc();
46 SwTextNode
* pTextNd
= rDoc
.GetNodes()[ m_nSttNode
]->GetTextNode();
47 SwTextNode
* pEndTextNd
= rDoc
.GetNodes()[ m_nEndNode
]->GetTextNode();
49 m_pHistory
.reset( new SwHistory
);
53 m_pHistory
->AddColl(pTextNd
->GetTextColl(), m_nSttNode
, SwNodeType::Text
);
54 if ( pTextNd
->GetpSwpHints() )
56 m_pHistory
->CopyAttr( pTextNd
->GetpSwpHints(), m_nSttNode
,
57 0, pTextNd
->GetText().getLength(), false );
59 if( pTextNd
->HasSwAttrSet() )
60 m_pHistory
->CopyFormatAttr( *pTextNd
->GetpSwAttrSet(), m_nSttNode
);
62 if( pEndTextNd
&& pEndTextNd
!= pTextNd
)
64 m_pHistory
->AddColl(pEndTextNd
->GetTextColl(), m_nEndNode
, SwNodeType::Text
);
65 if ( pEndTextNd
->GetpSwpHints() )
67 m_pHistory
->CopyAttr( pEndTextNd
->GetpSwpHints(), m_nEndNode
,
68 0, pEndTextNd
->GetText().getLength(), false );
70 if( pEndTextNd
->HasSwAttrSet() )
71 m_pHistory
->CopyFormatAttr( *pEndTextNd
->GetpSwAttrSet(), m_nEndNode
);
74 pTextNd
= rMvPos
.GetNode().GetTextNode();
75 if (nullptr != pTextNd
)
77 m_pHistory
->AddColl(pTextNd
->GetTextColl(), m_nMoveDestNode
, SwNodeType::Text
);
78 if ( pTextNd
->GetpSwpHints() )
80 m_pHistory
->CopyAttr( pTextNd
->GetpSwpHints(), m_nMoveDestNode
,
81 0, pTextNd
->GetText().getLength(), false );
83 if( pTextNd
->HasSwAttrSet() )
84 m_pHistory
->CopyFormatAttr( *pTextNd
->GetpSwAttrSet(), m_nMoveDestNode
);
87 m_nFootnoteStart
= m_pHistory
->Count();
88 DelFootnote( rRange
);
90 if( m_pHistory
&& !m_pHistory
->Count() )
94 SwUndoMove::SwUndoMove( SwDoc
& rDoc
, const SwNodeRange
& rRg
,
95 const SwNode
& rMvPos
)
96 : SwUndo(SwUndoId::MOVE
, &rDoc
)
100 , m_nMoveDestNode(rMvPos
.GetIndex())
101 , m_nDestStartContent(0)
102 , m_nDestEndContent(0)
103 , m_nInsPosContent(0)
104 , m_bMoveRedlines(false)
109 m_nSttContent
= m_nEndContent
= m_nMoveDestContent
= COMPLETE_STRING
;
111 m_nSttNode
= rRg
.aStart
.GetIndex();
112 m_nEndNode
= rRg
.aEnd
.GetIndex();
114 // DelFootnote( rRange );
115 // FIXME: duplication of the method body of DelFootnote below
117 // is the current move from ContentArea into the special section?
118 SwNodeOffset nContentStt
= rDoc
.GetNodes().GetEndOfAutotext().GetIndex();
119 if( m_nMoveDestNode
< nContentStt
&& rRg
.aStart
.GetIndex() > nContentStt
)
121 // delete all footnotes since they are undesired there
122 SwPosition
aPtPos( rRg
.aEnd
);
123 SwContentNode
* pCNd
= rRg
.aEnd
.GetNode().GetContentNode();
125 aPtPos
.SetContent( pCNd
->Len() );
126 SwPosition
aMkPos( rRg
.aStart
);
128 DelContentIndex( aMkPos
, aPtPos
, DelContentType::Ftn
);
130 if( m_pHistory
&& !m_pHistory
->Count() )
134 m_nFootnoteStart
= 0;
137 void SwUndoMove::SetDestRange( const SwNode
& rStt
,
139 const SwNodeIndex
& rInsPos
)
141 m_nDestStartNode
= rStt
.GetIndex();
142 m_nDestEndNode
= rEnd
.GetIndex();
143 if( m_nDestStartNode
> m_nDestEndNode
)
145 m_nDestStartNode
= m_nDestEndNode
;
146 m_nDestEndNode
= rStt
.GetIndex();
148 m_nInsPosNode
= rInsPos
.GetIndex();
150 m_nDestStartContent
= m_nDestEndContent
= m_nInsPosContent
= COMPLETE_STRING
;
153 void SwUndoMove::UndoImpl(::sw::UndoRedoContext
& rContext
)
155 SwDoc
*const pDoc
= & rContext
.GetDoc();
157 // Block so that we can jump out of it
159 // create index position and section based on the existing values
160 SwNodeIndex
aIdx( pDoc
->GetNodes(), m_nDestStartNode
);
164 // only a move with SwRange
165 SwNodeRange
aRg( aIdx
, aIdx
);
166 aRg
.aEnd
= m_nDestEndNode
;
167 aIdx
= m_nInsPosNode
;
168 bool bSuccess
= pDoc
->getIDocumentContentOperations().MoveNodeRange( aRg
, aIdx
.GetNode(),
169 SwMoveFlags::DEFAULT
);
175 SwPaM
aPam( aIdx
.GetNode(), m_nDestStartContent
,
176 *pDoc
->GetNodes()[ m_nDestEndNode
], m_nDestEndContent
);
178 // #i17764# if redlines are to be moved, we may not remove them
179 // before pDoc->Move gets a chance to handle them
180 if( ! m_bMoveRedlines
)
181 RemoveIdxFromRange( aPam
, false );
183 SwPosition
aPos( *pDoc
->GetNodes()[ m_nInsPosNode
] );
184 SwContentNode
* pCNd
= aPos
.GetNode().GetContentNode();
185 aPos
.SetContent( m_nInsPosContent
);
187 if( pCNd
->HasSwAttrSet() )
188 pCNd
->ResetAllAttr();
190 if( pCNd
->IsTextNode() && static_cast<SwTextNode
*>(pCNd
)->GetpSwpHints() )
191 static_cast<SwTextNode
*>(pCNd
)->ClearSwpHintsArr( false );
193 // first delete all attributes at InsertPos
194 const bool bSuccess
= pDoc
->getIDocumentContentOperations().MoveRange( aPam
, aPos
, m_bMoveRedlines
195 ? SwMoveFlags::REDLINES
196 : SwMoveFlags::DEFAULT
);
202 if( aPam
.GetPointNode().IsContentNode() )
203 aPam
.GetPointNode().GetContentNode()->ResetAllAttr();
204 // the Pam will be dropped now
207 SwTextNode
* pTextNd
= aIdx
.GetNode().GetTextNode();
211 RemoveIdxRel( aIdx
.GetIndex() + 1,
212 SwPosition( aIdx
, pTextNd
, pTextNd
->GetText().getLength()) );
214 // Are there any Pams in the next TextNode?
222 if( m_nFootnoteStart
!= m_pHistory
->Count() )
223 m_pHistory
->Rollback( pDoc
, m_nFootnoteStart
);
224 m_pHistory
->TmpRollback( pDoc
, 0 );
225 m_pHistory
->SetTmpEnd( m_pHistory
->Count() );
228 // set the cursor onto Undo area
231 AddUndoRedoPaM(rContext
);
235 void SwUndoMove::RedoImpl(::sw::UndoRedoContext
& rContext
)
237 SwPaM
& rPam
= AddUndoRedoPaM(rContext
);
238 SwDoc
& rDoc
= rContext
.GetDoc();
240 SwNodes
& rNds
= rDoc
.GetNodes();
241 SwNodeIndex
aIdx( rNds
, m_nMoveDestNode
);
245 // only a move with SwRange
246 SwNodeRange
aRg( rNds
, m_nSttNode
, m_nEndNode
);
247 rDoc
.getIDocumentContentOperations().MoveNodeRange( aRg
, aIdx
.GetNode(), m_bMoveRedlines
248 ? SwMoveFlags::REDLINES
249 : SwMoveFlags::DEFAULT
);
253 SwPaM
aPam(*rPam
.GetPoint());
255 SwPosition
aMvPos( aIdx
, aIdx
.GetNode().GetContentNode(), m_nMoveDestContent
);
258 RemoveIdxFromRange( aPam
, false );
260 aIdx
= aPam
.Start()->GetNode();
261 bool bJoinText
= aIdx
.GetNode().IsTextNode();
264 rDoc
.getIDocumentContentOperations().MoveRange( aPam
, aMvPos
,
265 SwMoveFlags::DEFAULT
);
267 if( m_nSttNode
!= m_nEndNode
&& bJoinText
)
270 SwTextNode
* pTextNd
= aIdx
.GetNode().GetTextNode();
271 if( pTextNd
&& pTextNd
->CanJoinNext() )
274 RemoveIdxRel( aIdx
.GetIndex() + 1,
275 SwPosition( *pTextNd
, pTextNd
->GetText().getLength()) );
280 *rPam
.GetPoint() = *aPam
.GetPoint();
282 *rPam
.GetMark() = *aPam
.GetMark();
286 void SwUndoMove::DelFootnote( const SwPaM
& rRange
)
288 // is the current move from ContentArea into the special section?
289 SwDoc
& rDoc
= rRange
.GetDoc();
290 SwNodeOffset nContentStt
= rDoc
.GetNodes().GetEndOfAutotext().GetIndex();
291 if( m_nMoveDestNode
< nContentStt
&&
292 rRange
.GetPoint()->GetNodeIndex() >= nContentStt
)
294 // delete all footnotes since they are undesired there
295 DelContentIndex( *rRange
.GetMark(), *rRange
.GetPoint(),
296 DelContentType::Ftn
);
298 if( m_pHistory
&& !m_pHistory
->Count() )
305 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */