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