LibreOffice Module sw (master) 1
unmove.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <UndoSplitMove.hxx>
21#include <doc.hxx>
22#include <pam.hxx>
23#include <swundo.hxx>
24#include <ndtxt.hxx>
25#include <UndoCore.hxx>
26#include <rolbck.hxx>
27
28// MOVE
29SwUndoMove::SwUndoMove( const SwPaM& rRange, const SwPosition& rMvPos )
30 : SwUndo( SwUndoId::MOVE, &rRange.GetDoc() )
31 , SwUndRng( rRange )
32 , m_nDestStartNode(0)
33 , m_nDestEndNode(0)
34 , m_nInsPosNode(0)
35 , m_nMoveDestNode(rMvPos.GetNodeIndex())
36 , m_nDestStartContent(0)
37 , m_nDestEndContent(0)
38 , m_nInsPosContent(0)
39 , m_nMoveDestContent(rMvPos.GetContentIndex())
40 , m_bJoinNext(false)
41 , m_bMoveRange(false)
42 , m_bMoveRedlines(false)
43{
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();
48
49 m_pHistory.reset( new SwHistory );
50
51 if( pTextNd )
52 {
54 if ( pTextNd->GetpSwpHints() )
55 {
56 m_pHistory->CopyAttr( pTextNd->GetpSwpHints(), m_nSttNode,
57 0, pTextNd->GetText().getLength(), false );
58 }
59 if( pTextNd->HasSwAttrSet() )
60 m_pHistory->CopyFormatAttr( *pTextNd->GetpSwAttrSet(), m_nSttNode );
61 }
62 if( pEndTextNd && pEndTextNd != pTextNd )
63 {
64 m_pHistory->Add( pEndTextNd->GetTextColl(), m_nEndNode, SwNodeType::Text );
65 if ( pEndTextNd->GetpSwpHints() )
66 {
67 m_pHistory->CopyAttr( pEndTextNd->GetpSwpHints(), m_nEndNode,
68 0, pEndTextNd->GetText().getLength(), false );
69 }
70 if( pEndTextNd->HasSwAttrSet() )
71 m_pHistory->CopyFormatAttr( *pEndTextNd->GetpSwAttrSet(), m_nEndNode );
72 }
73
74 pTextNd = rMvPos.GetNode().GetTextNode();
75 if (nullptr != pTextNd)
76 {
78 if ( pTextNd->GetpSwpHints() )
79 {
80 m_pHistory->CopyAttr( pTextNd->GetpSwpHints(), m_nMoveDestNode,
81 0, pTextNd->GetText().getLength(), false );
82 }
83 if( pTextNd->HasSwAttrSet() )
84 m_pHistory->CopyFormatAttr( *pTextNd->GetpSwAttrSet(), m_nMoveDestNode );
85 }
86
88 DelFootnote( rRange );
89
90 if( m_pHistory && !m_pHistory->Count() )
91 m_pHistory.reset();
92}
93
95 const SwNode& rMvPos )
96 : SwUndo(SwUndoId::MOVE, &rDoc)
97 , m_nDestStartNode(0)
98 , m_nDestEndNode(0)
99 , m_nInsPosNode(0)
100 , m_nMoveDestNode(rMvPos.GetIndex())
101 , m_nDestStartContent(0)
102 , m_nDestEndContent(0)
103 , m_nInsPosContent(0)
104 , m_bMoveRedlines(false)
105{
106 m_bMoveRange = true;
107 m_bJoinNext = false;
108
110
111 m_nSttNode = rRg.aStart.GetIndex();
112 m_nEndNode = rRg.aEnd.GetIndex();
113
114// DelFootnote( rRange );
115// FIXME: duplication of the method body of DelFootnote below
116
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 )
120 {
121 // delete all footnotes since they are undesired there
122 SwPosition aPtPos( rRg.aEnd );
124 if( pCNd )
125 aPtPos.nContent.Assign( pCNd, pCNd->Len() );
126 SwPosition aMkPos( rRg.aStart );
127
128 DelContentIndex( aMkPos, aPtPos, DelContentType::Ftn );
129
130 if( m_pHistory && !m_pHistory->Count() )
131 m_pHistory.reset();
132 }
133
135}
136
138 const SwNode& rEnd,
139 const SwNodeIndex& rInsPos )
140{
141 m_nDestStartNode = rStt.GetIndex();
142 m_nDestEndNode = rEnd.GetIndex();
144 {
146 m_nDestEndNode = rStt.GetIndex();
147 }
148 m_nInsPosNode = rInsPos.GetIndex();
149
151}
152
154{
155 SwDoc *const pDoc = & rContext.GetDoc();
156
157 // Block so that we can jump out of it
158 do {
159 // create index position and section based on the existing values
160 SwNodeIndex aIdx( pDoc->GetNodes(), m_nDestStartNode );
161
162 if( m_bMoveRange )
163 {
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(),
170 if (!bSuccess)
171 break;
172 }
173 else
174 {
175 SwPaM aPam( aIdx.GetNode(), m_nDestStartContent,
177
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 );
182
183 SwPosition aPos( *pDoc->GetNodes()[ m_nInsPosNode] );
184 SwContentNode* pCNd = aPos.GetNode().GetContentNode();
185 aPos.nContent.Assign( pCNd, m_nInsPosContent );
186
187 if( pCNd->HasSwAttrSet() )
188 pCNd->ResetAllAttr();
189
190 if( pCNd->IsTextNode() && static_cast<SwTextNode*>(pCNd)->GetpSwpHints() )
191 static_cast<SwTextNode*>(pCNd)->ClearSwpHintsArr( false );
192
193 // first delete all attributes at InsertPos
194 const bool bSuccess = pDoc->getIDocumentContentOperations().MoveRange( aPam, aPos, m_bMoveRedlines
197 if (!bSuccess)
198 break;
199
200 aPam.Exchange();
201 aPam.DeleteMark();
202 if( aPam.GetPointNode().IsContentNode() )
204 // the Pam will be dropped now
205 }
206
207 SwTextNode* pTextNd = aIdx.GetNode().GetTextNode();
208 if( m_bJoinNext )
209 {
210 {
211 RemoveIdxRel( aIdx.GetIndex() + 1,
212 SwPosition( aIdx, pTextNd, pTextNd->GetText().getLength()) );
213 }
214 // Are there any Pams in the next TextNode?
215 pTextNd->JoinNext();
216 }
217
218 } while( false );
219
220 if( m_pHistory )
221 {
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() );
226 }
227
228 // set the cursor onto Undo area
229 if( !m_bMoveRange )
230 {
231 AddUndoRedoPaM(rContext);
232 }
233}
234
236{
237 SwPaM& rPam = AddUndoRedoPaM(rContext);
238 SwDoc& rDoc = rContext.GetDoc();
239
240 SwNodes& rNds = rDoc.GetNodes();
241 SwNodeIndex aIdx( rNds, m_nMoveDestNode );
242
243 if( m_bMoveRange )
244 {
245 // only a move with SwRange
246 SwNodeRange aRg( rNds, m_nSttNode, m_nEndNode );
250 }
251 else
252 {
253 SwPaM aPam(*rPam.GetPoint());
254 SetPaM( aPam );
255 SwPosition aMvPos( aIdx, aIdx.GetNode().GetContentNode(), m_nMoveDestContent );
256
257 DelFootnote( aPam );
258 RemoveIdxFromRange( aPam, false );
259
260 aIdx = aPam.Start()->GetNode();
261 bool bJoinText = aIdx.GetNode().IsTextNode();
262
263 --aIdx;
264 rDoc.getIDocumentContentOperations().MoveRange( aPam, aMvPos,
266
267 if( m_nSttNode != m_nEndNode && bJoinText )
268 {
269 ++aIdx;
270 SwTextNode * pTextNd = aIdx.GetNode().GetTextNode();
271 if( pTextNd && pTextNd->CanJoinNext() )
272 {
273 {
274 RemoveIdxRel( aIdx.GetIndex() + 1,
275 SwPosition( *pTextNd, pTextNd->GetText().getLength()) );
276 }
277 pTextNd->JoinNext();
278 }
279 }
280 *rPam.GetPoint() = *aPam.GetPoint();
281 rPam.SetMark();
282 *rPam.GetMark() = *aPam.GetMark();
283 }
284}
285
286void SwUndoMove::DelFootnote( const SwPaM& rRange )
287{
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 )
293 {
294 // delete all footnotes since they are undesired there
295 DelContentIndex( *rRange.GetMark(), *rRange.GetPoint(),
297
298 if( m_pHistory && !m_pHistory->Count() )
299 {
300 m_pHistory.reset();
301 }
302 }
303}
304
305/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool MoveRange(SwPaM &, SwPosition &, SwMoveFlags)=0
virtual bool MoveNodeRange(SwNodeRange &, SwNode &, SwMoveFlags)=0
SwContentIndex & Assign(const SwContentNode *, sal_Int32)
Definition: index.cxx:206
bool HasSwAttrSet() const
Definition: node.hxx:473
bool CanJoinNext(SwNodeIndex *pIdx=nullptr) const
Is it possible to join two nodes? In pIdx the second position can be returned.
Definition: node.cxx:1844
virtual sal_Int32 Len() const
Definition: node.cxx:1257
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:472
virtual sal_uInt16 ResetAllAttr()
Definition: node.cxx:1749
Definition: doc.hxx:192
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:316
SwNodes & GetNodes()
Definition: doc.hxx:413
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:136
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:171
SwNodeIndex aStart
Definition: ndindex.hxx:149
SwNodeIndex aEnd
Definition: ndindex.hxx:150
Base class of the Writer document model elements.
Definition: node.hxx:84
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:876
SwNodeOffset GetIndex() const
Definition: node.hxx:296
bool IsContentNode() const
Definition: node.hxx:656
bool IsTextNode() const
Definition: node.hxx:664
SwContentNode * GetContentNode()
Definition: node.hxx:643
SwNode & GetEndOfAutotext() const
Section for all Flys/Header/Footers.
Definition: ndarr.hxx:158
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
const SwPosition * GetMark() const
Definition: pam.hxx:263
SwNode & GetPointNode() const
Definition: pam.hxx:283
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:612
void Exchange()
Definition: pam.cxx:626
SwDoc & GetDoc() const
Definition: pam.hxx:299
void DeleteMark()
Definition: pam.hxx:231
const SwPosition * GetPoint() const
Definition: pam.hxx:261
const SwPosition * Start() const
Definition: pam.hxx:266
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:86
virtual SwContentNode * JoinNext() override
Definition: ndtxt.cxx:980
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:230
const OUString & GetText() const
Definition: ndtxt.hxx:222
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:870
SwPaM & AddUndoRedoPaM(::sw::UndoRedoContext &, bool const bCorrToContent=false) const
Definition: undobj.cxx:100
void SetPaM(SwPaM &, bool bCorrToContent=false) const
Definition: undobj.cxx:80
sal_Int32 m_nSttContent
Definition: undobj.hxx:232
SwNodeOffset m_nSttNode
Definition: undobj.hxx:231
SwNodeOffset m_nEndNode
Definition: undobj.hxx:231
sal_Int32 m_nEndContent
Definition: undobj.hxx:232
virtual void RedoImpl(::sw::UndoRedoContext &) override
Definition: unmove.cxx:235
sal_uInt16 m_nFootnoteStart
SwNodeOffset m_nDestEndNode
sal_Int32 m_nMoveDestContent
bool m_bMoveRedlines
SwNodeOffset m_nMoveDestNode
void SetDestRange(const SwNode &rStt, const SwNode &rEnd, const SwNodeIndex &rInsPos)
set the destination range after the move
Definition: unmove.cxx:137
SwNodeOffset m_nInsPosNode
SwUndoMove(const SwPaM &, const SwPosition &)
Definition: unmove.cxx:29
sal_Int32 m_nInsPosContent
sal_Int32 m_nDestStartContent
sal_Int32 m_nDestEndContent
void DelFootnote(const SwPaM &)
Definition: unmove.cxx:286
SwNodeOffset m_nDestStartNode
virtual void UndoImpl(::sw::UndoRedoContext &) override
Definition: unmove.cxx:153
void DelContentIndex(const SwPosition &pMark, const SwPosition &pPoint, DelContentType nDelContentType=DelContentType::AllMask)
Definition: undobj.cxx:861
std::unique_ptr< SwHistory > m_pHistory
Definition: undobj.hxx:167
static void RemoveIdxRel(SwNodeOffset, const SwPosition &)
Definition: undobj.cxx:144
static void RemoveIdxFromRange(SwPaM &rPam, bool bMoveNext)
Definition: undobj.cxx:118
SwDoc & GetDoc() const
Definition: UndoCore.hxx:95
Marks a position in the document model.
Definition: pam.hxx:37
SwNode & GetNode() const
Definition: pam.hxx:80
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:77
SwContentIndex nContent
Definition: pam.hxx:39
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
SwUndoId
Definition: swundo.hxx:30