LibreOffice Module sw (master)  1
doccorr.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 <doc.hxx>
22 #include <node.hxx>
23 #include <rootfrm.hxx>
24 #include <editsh.hxx>
25 #include <viscrs.hxx>
26 #include <IMark.hxx>
27 #include <bookmrk.hxx>
28 #include <redline.hxx>
29 #include <mvsave.hxx>
30 #include <docary.hxx>
31 #include <unocrsr.hxx>
32 #include <swundo.hxx>
33 #include <hints.hxx>
34 #include <edimp.hxx>
35 
36 namespace
37 {
40  const SwStartNode* lcl_FindUnoCursorSection( const SwNode& rNode )
41  {
42  const SwStartNode* pStartNode = rNode.StartOfSectionNode();
43  while( ( pStartNode != nullptr ) &&
44  ( pStartNode->StartOfSectionNode() != pStartNode ) &&
45  ( pStartNode->GetStartNodeType() == SwNormalStartNode ) )
46  pStartNode = pStartNode->StartOfSectionNode();
47 
48  return pStartNode;
49  }
50 
51  bool lcl_PosCorrAbs(SwPosition & rPos,
52  const SwPosition& rStart,
53  const SwPosition& rEnd,
54  const SwPosition& rNewPos)
55  {
56  if ((rStart <= rPos) && (rPos <= rEnd))
57  {
58  rPos = rNewPos;
59  return true;
60  }
61  return false;
62  };
63 
64  bool lcl_PaMCorrAbs(SwPaM & rPam,
65  const SwPosition& rStart,
66  const SwPosition& rEnd,
67  const SwPosition& rNewPos)
68  {
69  bool bRet = false;
70  bRet |= lcl_PosCorrAbs(rPam.GetBound(), rStart, rEnd, rNewPos);
71  bRet |= lcl_PosCorrAbs(rPam.GetBound(false), rStart, rEnd, rNewPos);
72  return bRet;
73  };
74 
75  void lcl_PaMCorrRel1(SwPaM * pPam,
76  SwNode const * const pOldNode,
77  const SwPosition& rNewPos,
78  const sal_Int32 nCntIdx)
79  {
80  for(int nb = 0; nb < 2; ++nb)
81  if(&(pPam->GetBound(bool(nb)).nNode.GetNode()) == pOldNode)
82  {
83  pPam->GetBound(bool(nb)).nNode = rNewPos.nNode;
84  pPam->GetBound(bool(nb)).nContent.Assign(
85  const_cast<SwIndexReg*>(rNewPos.nContent.GetIdxReg()),
86  nCntIdx + pPam->GetBound(bool(nb)).nContent.GetIndex());
87  }
88  }
89 }
90 
91 void PaMCorrAbs( const SwPaM& rRange,
92  const SwPosition& rNewPos )
93 {
94  SwPosition const aStart( *rRange.Start() );
95  SwPosition const aEnd( *rRange.End() );
96  SwPosition const aNewPos( rNewPos );
97  SwDoc *const pDoc = aStart.nNode.GetNode().GetDoc();
98  SwCursorShell *const pShell = pDoc->GetEditShell();
99 
100  if( pShell )
101  {
102  for(const SwViewShell& rShell : pShell->GetRingContainer())
103  {
104  if(dynamic_cast<const SwCursorShell *>(&rShell) == nullptr)
105  continue;
106  const SwCursorShell* pCursorShell = static_cast<const SwCursorShell*>(&rShell);
107  SwPaM *_pStackCursor = pCursorShell->GetStackCursor();
108  if( _pStackCursor )
109  do {
110  lcl_PaMCorrAbs( *_pStackCursor, aStart, aEnd, aNewPos );
111  } while ( (_pStackCursor != nullptr ) &&
112  ((_pStackCursor = _pStackCursor->GetNext()) != pCursorShell->GetStackCursor()) );
113 
114  for(SwPaM& rPaM : const_cast<SwShellCursor*>(pCursorShell->GetCursor_())->GetRingContainer())
115  {
116  lcl_PaMCorrAbs( rPaM, aStart, aEnd, aNewPos );
117  }
118 
119  if( pCursorShell->IsTableMode() )
120  lcl_PaMCorrAbs( const_cast<SwPaM &>(*pCursorShell->GetTableCrs()), aStart, aEnd, aNewPos );
121  }
122  }
123 
124  pDoc->cleanupUnoCursorTable();
125  for(const auto& pWeakUnoCursor : pDoc->mvUnoCursorTable)
126  {
127  auto pUnoCursor(pWeakUnoCursor.lock());
128  if(!pUnoCursor)
129  continue;
130 
131  bool bChange = false; // has the UNO cursor been corrected?
132 
133  // determine whether the UNO cursor will leave it's designated
134  // section
135  bool const bLeaveSection =
136  pUnoCursor->IsRemainInSection() &&
137  ( lcl_FindUnoCursorSection( aNewPos.nNode.GetNode() ) !=
138  lcl_FindUnoCursorSection(
139  pUnoCursor->GetPoint()->nNode.GetNode() ) );
140 
141  for(SwPaM& rPaM : pUnoCursor->GetRingContainer())
142  {
143  bChange |= lcl_PaMCorrAbs( rPaM, aStart, aEnd, aNewPos );
144  }
145 
146  SwUnoTableCursor *const pUnoTableCursor =
147  dynamic_cast<SwUnoTableCursor *>(pUnoCursor.get());
148  if( pUnoTableCursor )
149  {
150  for(SwPaM& rPaM : pUnoTableCursor->GetSelRing().GetRingContainer())
151  {
152  bChange |=
153  lcl_PaMCorrAbs( rPaM, aStart, aEnd, aNewPos );
154  }
155  }
156 
157  // if a UNO cursor leaves its designated section, we must inform
158  // (and invalidate) said cursor
159  if (bChange && bLeaveSection)
160  {
161  // the UNO cursor has left its section. We need to notify it!
162  sw::UnoCursorHint aHint;
163  pUnoCursor->m_aNotifier.Broadcast(aHint);
164  }
165  }
166 }
167 
168 void SwDoc::CorrAbs(const SwNodeIndex& rOldNode,
169  const SwPosition& rNewPos,
170  const sal_Int32 nOffset,
171  bool bMoveCursor)
172 {
173  SwContentNode *const pContentNode( rOldNode.GetNode().GetContentNode() );
174  SwPaM const aPam(rOldNode, 0,
175  rOldNode, pContentNode ? pContentNode->Len() : 0);
176  SwPosition aNewPos(rNewPos);
177  aNewPos.nContent += nOffset;
178 
179  getIDocumentMarkAccess()->correctMarksAbsolute(rOldNode, rNewPos, nOffset);
180  // fix redlines
181  {
183  for (SwRedlineTable::size_type n = 0; n < rTable.size(); )
184  {
185  // is on position ??
186  SwRangeRedline *const pRedline( rTable[ n ] );
187  bool const bChanged =
188  lcl_PaMCorrAbs(*pRedline, *aPam.Start(), *aPam.End(), aNewPos);
189  // clean up empty redlines: docredln.cxx asserts these as invalid
190  if (bChanged && (*pRedline->GetPoint() == *pRedline->GetMark())
191  && (pRedline->GetContentIdx() == nullptr))
192  {
193  rTable.DeleteAndDestroy(n);
194  }
195  else
196  {
197  ++n;
198  }
199  }
200 
201  // To-Do - need to add here 'SwExtraRedlineTable' also ?
202  }
203 
204  if(bMoveCursor)
205  {
206  ::PaMCorrAbs(aPam, aNewPos);
207  }
208 }
209 
211  const SwPaM& rRange,
212  const SwPosition& rNewPos,
213  bool bMoveCursor )
214 {
215  SwPosition aStart(*rRange.Start());
216  SwPosition aEnd(*rRange.End());
217 
218  DelBookmarks( aStart.nNode, aEnd.nNode, nullptr, &aStart.nContent, &aEnd.nContent );
219 
220  if(bMoveCursor)
221  ::PaMCorrAbs(rRange, rNewPos);
222 }
223 
225  const SwNodeIndex& rStartNode,
226  const SwNodeIndex& rEndNode,
227  const SwPosition& rNewPos,
228  bool bMoveCursor )
229 {
230  DelBookmarks( rStartNode, rEndNode );
231 
232  if(bMoveCursor)
233  {
234  SwContentNode *const pContentNode( rEndNode.GetNode().GetContentNode() );
235  SwPaM const aPam(rStartNode, 0,
236  rEndNode, pContentNode ? pContentNode->Len() : 0);
237  ::PaMCorrAbs(aPam, rNewPos);
238  }
239 }
240 
241 void PaMCorrRel( const SwNodeIndex &rOldNode,
242  const SwPosition &rNewPos,
243  const sal_Int32 nOffset )
244 {
245  const SwNode* pOldNode = &rOldNode.GetNode();
246  SwPosition aNewPos( rNewPos );
247  const SwDoc* pDoc = pOldNode->GetDoc();
248 
249  const sal_Int32 nCntIdx = rNewPos.nContent.GetIndex() + nOffset;
250 
251  SwCursorShell const* pShell = pDoc->GetEditShell();
252  if( pShell )
253  {
254  for(const SwViewShell& rShell : pShell->GetRingContainer())
255  {
256  if(dynamic_cast<const SwCursorShell *>(&rShell) == nullptr)
257  continue;
258  SwCursorShell* pCursorShell = const_cast<SwCursorShell*>(static_cast<const SwCursorShell*>(&rShell));
259  SwPaM *_pStackCursor = pCursorShell->GetStackCursor();
260  if( _pStackCursor )
261  do {
262  lcl_PaMCorrRel1( _pStackCursor, pOldNode, aNewPos, nCntIdx );
263  } while ( (_pStackCursor != nullptr ) &&
264  ((_pStackCursor = _pStackCursor->GetNext()) != pCursorShell->GetStackCursor()) );
265 
266  SwPaM* pStartPaM = pCursorShell->GetCursor_();
267  for(SwPaM& rPaM : pStartPaM->GetRingContainer())
268  {
269  lcl_PaMCorrRel1( &rPaM, pOldNode, aNewPos, nCntIdx);
270  }
271 
272  if( pCursorShell->IsTableMode() )
273  lcl_PaMCorrRel1( pCursorShell->GetTableCrs(), pOldNode, aNewPos, nCntIdx );
274  }
275  }
276 
277  pDoc->cleanupUnoCursorTable();
278  for(const auto& pWeakUnoCursor : pDoc->mvUnoCursorTable)
279  {
280  auto pUnoCursor(pWeakUnoCursor.lock());
281  if(!pUnoCursor)
282  continue;
283  for(SwPaM& rPaM : pUnoCursor->GetRingContainer())
284  {
285  lcl_PaMCorrRel1( &rPaM, pOldNode, aNewPos, nCntIdx );
286  }
287 
288  SwUnoTableCursor* pUnoTableCursor =
289  dynamic_cast<SwUnoTableCursor*>(pUnoCursor.get());
290  if( pUnoTableCursor )
291  {
292  for(SwPaM& rPaM : pUnoTableCursor->GetSelRing().GetRingContainer())
293  {
294  lcl_PaMCorrRel1( &rPaM, pOldNode, aNewPos, nCntIdx );
295  }
296  }
297  }
298 }
299 
300 void SwDoc::CorrRel(const SwNodeIndex& rOldNode,
301  const SwPosition& rNewPos,
302  const sal_Int32 nOffset,
303  bool bMoveCursor)
304 {
305  getIDocumentMarkAccess()->correctMarksRelative(rOldNode, rNewPos, nOffset);
306 
307  { // fix the Redlines
309  SwPosition aNewPos(rNewPos);
310  for(SwRangeRedline* p : rTable)
311  {
312  // lies on the position ??
313  lcl_PaMCorrRel1( p, &rOldNode.GetNode(), aNewPos, aNewPos.nContent.GetIndex() + nOffset );
314  }
315 
316  // To-Do - need to add here 'SwExtraRedlineTable' also ?
317  }
318 
319  if(bMoveCursor)
320  ::PaMCorrRel(rOldNode, rNewPos, nOffset);
321 }
322 
324 {
325  SwViewShell const *pCurrentView = getIDocumentLayoutAccess().GetCurrentViewShell();
326  // Layout and OLE shells should be available
327  if( pCurrentView )
328  {
329  for(const SwViewShell& rCurrentSh : pCurrentView->GetRingContainer())
330  {
331  // look for an EditShell (if it exists)
332  if( dynamic_cast<const SwEditShell *>(&rCurrentSh) != nullptr )
333  {
334  return static_cast<const SwEditShell*>(&rCurrentSh);
335  }
336  }
337  }
338  return nullptr;
339 }
340 
342 {
343  return const_cast<SwEditShell*>( const_cast<SwDoc const *>( this )->GetEditShell() );
344 }
345 
347 {
348  return GetEditShell();
349 }
350 
351 //bool foo()
352 //{
353 // bool b1 = true ? true : false;
354 // bool b2 = (true ? true : false) ? true : false;
355 // bool b3 = true ? (true ? true : false) : false;
356 // bool b4 = true ? true : (true ? true : false);
357 // return false;
358 //}
359 
360 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Starts a section of nodes in the document model.
Definition: node.hxx:303
Marks a position in the document model.
Definition: pam.hxx:35
void DelBookmarks(const SwNodeIndex &rStt, const SwNodeIndex &rEnd, std::vector< SaveBookmark > *pSaveBkmk, const SwIndex *pSttIdx, const SwIndex *pEndIdx)
Definition: docbm.cxx:1656
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsTableMode() const
Definition: crsrsh.hxx:646
const SwPosition * GetMark() const
Definition: pam.hxx:209
virtual void correctMarksRelative(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset)=0
Corrects marks (relative) This method uses the previous position of the mark in the paragraph as offs...
Definition: doc.hxx:185
SwNode & GetNode() const
Definition: ndindex.hxx:118
SwPosition & GetBound(bool bOne=true)
Definition: pam.hxx:245
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1552
SwPaM * GetStackCursor() const
Definition: crsrsh.hxx:872
size_type size() const
Definition: docary.hxx:368
void cleanupUnoCursorTable() const
Definition: doc.hxx:1628
SwIndex nContent
Definition: pam.hxx:38
SwPaM * GetNext()
Definition: pam.hxx:264
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:331
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
const SwPaM * GetTableCrs() const
Definition: crsrsh.hxx:903
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
void DeleteAndDestroy(size_type nPos)
Definition: docredln.cxx:635
const SwPosition * GetPoint() const
Definition: pam.hxx:207
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:323
std::vector< std::weak_ptr< SwUnoCursor > > mvUnoCursorTable
Definition: doc.hxx:1625
SwContentNode * GetContentNode()
Definition: node.hxx:615
vector_type::size_type size_type
Definition: docary.hxx:330
SwDoc * GetDoc()
Definition: node.hxx:702
void PaMCorrRel(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset)
Sets all PaMs in OldNode to relative Pos.
Definition: doccorr.cxx:241
Marks a node in the document model.
Definition: ndindex.hxx:31
ring_container GetRingContainer()
Definition: ring.hxx:240
SwStartNodeType GetStartNodeType() const
Definition: node.hxx:320
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:437
const SwPosition * Start() const
Definition: pam.hxx:212
The Undo actions need to create new Shell cursors.
void CorrRel(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset=0, bool bMoveCursor=false)
Definition: doccorr.cxx:300
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:367
void CorrAbs(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset=0, bool bMoveCursor=false)
Definition: doccorr.cxx:168
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
sal_Int32 GetIndex() const
Definition: index.hxx:95
const SwPosition * End() const
Definition: pam.hxx:217
void PaMCorrAbs(const SwPaM &rRange, const SwPosition &rNewPos)
Function declarations so that everything below the CursorShell can move the Cursor once in a while...
Definition: doccorr.cxx:91
SwCursor & GetSelRing()
Definition: unocrsr.hxx:100
virtual void correctMarksAbsolute(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset)=0
Corrects marks (absolute) This method ignores the previous position of the mark in the paragraph...
virtual const SwRedlineTable & GetRedlineTable() const =0
const SwIndexReg * GetIdxReg() const
Definition: index.hxx:101
::sw::IShellCursorSupplier * GetIShellCursorSupplier()
Definition: doccorr.cxx:346
SwNodeIndex * GetContentIdx() const
Definition: redline.hxx:184
Base class of the Writer document model elements.
Definition: node.hxx:79