android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / core / doc / doccorr.cxx
blob783e1aa2346f63bae5fccb700b406f646bf840ed
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <doc.hxx>
21 #include <IDocumentLayoutAccess.hxx>
22 #include <IDocumentRedlineAccess.hxx>
23 #include <node.hxx>
24 #include <editsh.hxx>
25 #include <viscrs.hxx>
26 #include <redline.hxx>
27 #include <mvsave.hxx>
28 #include <docary.hxx>
29 #include <unocrsr.hxx>
31 namespace
33 /// find the relevant section in which the SwUnoCursor may wander.
34 /// returns NULL if no restrictions apply
35 const SwStartNode* lcl_FindUnoCursorSection( const SwNode& rNode )
37 const SwStartNode* pStartNode = rNode.IsStartNode() ? rNode.GetStartNode() : rNode.StartOfSectionNode();
38 while( ( pStartNode != nullptr ) &&
39 ( pStartNode->StartOfSectionNode() != pStartNode ) &&
40 // section node is only start node allowing overlapped delete
41 pStartNode->IsSectionNode() )
43 pStartNode = pStartNode->StartOfSectionNode();
46 return pStartNode;
49 bool lcl_PosCorrAbs(SwPosition & rPos,
50 const SwPosition& rStart,
51 const SwPosition& rEnd,
52 const SwPosition& rNewPos)
54 if ((rStart <= rPos) && (rPos <= rEnd))
56 rPos = rNewPos;
57 return true;
59 return false;
62 bool lcl_PaMCorrAbs(SwPaM & rPam,
63 const SwPosition& rStart,
64 const SwPosition& rEnd,
65 const SwPosition& rNewPos)
67 bool bRet = false;
68 bRet |= lcl_PosCorrAbs(rPam.GetBound(), rStart, rEnd, rNewPos);
69 bRet |= lcl_PosCorrAbs(rPam.GetBound(false), rStart, rEnd, rNewPos);
70 return bRet;
73 void lcl_PaMCorrRel1(SwPaM * pPam,
74 SwNode const * const pOldNode,
75 const SwPosition& rNewPos,
76 const sal_Int32 nCntIdx)
78 for(int nb = 0; nb < 2; ++nb)
80 SwPosition & rPos = pPam->GetBound(bool(nb));
81 if(&rPos.GetNode() == pOldNode)
83 rPos.Assign(rNewPos.GetNode(), SwNodeOffset(0),
84 nCntIdx + rPos.GetContentIndex());
90 void PaMCorrAbs( const SwPaM& rRange,
91 const SwPosition& rNewPos )
93 SwPosition const aStart( *rRange.Start() );
94 SwPosition const aEnd( *rRange.End() );
95 SwPosition const aNewPos( rNewPos );
96 SwDoc& rDoc = aStart.GetNode().GetDoc();
98 if (SwCursorShell *const pShell = rDoc.GetEditShell())
100 for(const SwViewShell& rShell : pShell->GetRingContainer())
102 const SwCursorShell* pCursorShell = dynamic_cast<const SwCursorShell*>(&rShell);
103 if(!pCursorShell)
104 continue;
105 SwPaM *_pStackCursor = pCursorShell->GetStackCursor();
106 if( _pStackCursor )
107 for (;;)
109 lcl_PaMCorrAbs( *_pStackCursor, aStart, aEnd, aNewPos );
110 if( !_pStackCursor )
111 break;
112 _pStackCursor = _pStackCursor->GetNext();
113 if( _pStackCursor == pCursorShell->GetStackCursor() )
114 break;
117 for(SwPaM& rPaM : const_cast<SwShellCursor*>(pCursorShell->GetCursor_())->GetRingContainer())
119 lcl_PaMCorrAbs( rPaM, aStart, aEnd, aNewPos );
122 if( pCursorShell->IsTableMode() )
123 lcl_PaMCorrAbs( const_cast<SwPaM &>(*pCursorShell->GetTableCrs()), aStart, aEnd, aNewPos );
127 rDoc.cleanupUnoCursorTable();
128 for(const auto& pWeakUnoCursor : rDoc.mvUnoCursorTable)
130 auto pUnoCursor(pWeakUnoCursor.lock());
131 if(!pUnoCursor)
132 continue;
134 bool bChange = false; // has the UNO cursor been corrected?
136 // determine whether the UNO cursor will leave it's designated
137 // section
138 bool const bLeaveSection =
139 pUnoCursor->IsRemainInSection() &&
140 ( lcl_FindUnoCursorSection( aNewPos.GetNode() ) !=
141 lcl_FindUnoCursorSection(
142 pUnoCursor->GetPoint()->GetNode() ) );
144 for(SwPaM& rPaM : pUnoCursor->GetRingContainer())
146 bChange |= lcl_PaMCorrAbs( rPaM, aStart, aEnd, aNewPos );
149 SwUnoTableCursor *const pUnoTableCursor =
150 dynamic_cast<SwUnoTableCursor *>(pUnoCursor.get());
151 if( pUnoTableCursor )
153 for(SwPaM& rPaM : pUnoTableCursor->GetSelRing().GetRingContainer())
155 bChange |=
156 lcl_PaMCorrAbs( rPaM, aStart, aEnd, aNewPos );
160 // if a UNO cursor leaves its designated section, we must inform
161 // (and invalidate) said cursor
162 if (bChange && bLeaveSection)
164 // the UNO cursor has left its section. We need to notify it!
165 sw::UnoCursorHint aHint;
166 pUnoCursor->m_aNotifier.Broadcast(aHint);
171 void SwDoc::CorrAbs(const SwNode& rOldNode,
172 const SwPosition& rNewPos,
173 const sal_Int32 nOffset,
174 bool bMoveCursor)
176 const SwContentNode *const pContentNode( rOldNode.GetContentNode() );
177 SwPaM const aPam(rOldNode, 0,
178 rOldNode, pContentNode ? pContentNode->Len() : 0);
179 SwPosition aNewPos(rNewPos);
180 aNewPos.AdjustContent(nOffset);
182 getIDocumentMarkAccess()->correctMarksAbsolute(rOldNode, rNewPos, nOffset);
183 // fix redlines
185 SwRedlineTable& rTable = getIDocumentRedlineAccess().GetRedlineTable();
186 for (SwRedlineTable::size_type n = 0; n < rTable.size(); )
188 // is on position ??
189 SwRangeRedline *const pRedline( rTable[ n ] );
190 bool const bChanged =
191 lcl_PaMCorrAbs(*pRedline, *aPam.Start(), *aPam.End(), aNewPos);
192 // clean up empty redlines: docredln.cxx asserts these as invalid
193 if (bChanged && (*pRedline->GetPoint() == *pRedline->GetMark())
194 && (pRedline->GetContentIdx() == nullptr))
196 rTable.DeleteAndDestroy(n);
198 else
200 ++n;
204 // To-Do - need to add here 'SwExtraRedlineTable' also ?
207 if(bMoveCursor)
209 ::PaMCorrAbs(aPam, aNewPos);
213 void SwDoc::CorrAbs(
214 const SwPaM& rRange,
215 const SwPosition& rNewPos,
216 bool bMoveCursor )
218 const SwPosition& aStart(*rRange.Start());
219 const SwPosition& aEnd(*rRange.End());
221 DelBookmarks( aStart.GetNode(), aEnd.GetNode(), nullptr, aStart.GetContentIndex(), aEnd.GetContentIndex() );
223 if(bMoveCursor)
224 ::PaMCorrAbs(rRange, rNewPos);
227 void SwDoc::CorrAbs(
228 const SwNodeIndex& rStartNode,
229 const SwNodeIndex& rEndNode,
230 const SwPosition& rNewPos,
231 bool bMoveCursor )
233 DelBookmarks( rStartNode.GetNode(), rEndNode.GetNode() );
235 if(bMoveCursor)
237 SwContentNode *const pContentNode( rEndNode.GetNode().GetContentNode() );
238 SwPaM const aPam(rStartNode, 0,
239 rEndNode, pContentNode ? pContentNode->Len() : 0);
240 ::PaMCorrAbs(aPam, rNewPos);
244 void PaMCorrRel( const SwNode &rOldNode,
245 const SwPosition &rNewPos,
246 const sal_Int32 nOffset )
248 const SwNode* pOldNode = &rOldNode;
249 SwPosition aNewPos( rNewPos );
250 const SwDoc& rDoc = pOldNode->GetDoc();
252 const sal_Int32 nCntIdx = rNewPos.GetContentIndex() + nOffset;
254 if (SwCursorShell const* pShell = rDoc.GetEditShell())
256 for(const SwViewShell& rShell : pShell->GetRingContainer())
258 SwCursorShell* pCursorShell = const_cast<SwCursorShell*>(dynamic_cast<const SwCursorShell*>(&rShell));
259 if(!pCursorShell)
260 continue;
261 SwPaM *_pStackCursor = pCursorShell->GetStackCursor();
262 if( _pStackCursor )
263 for (;;)
265 lcl_PaMCorrRel1( _pStackCursor, pOldNode, aNewPos, nCntIdx );
266 if( !_pStackCursor )
267 break;
268 _pStackCursor = _pStackCursor->GetNext();
269 if( _pStackCursor == pCursorShell->GetStackCursor() )
270 break;
273 SwPaM* pStartPaM = pCursorShell->GetCursor_();
274 for(SwPaM& rPaM : pStartPaM->GetRingContainer())
276 lcl_PaMCorrRel1( &rPaM, pOldNode, aNewPos, nCntIdx);
279 if( pCursorShell->IsTableMode() )
280 lcl_PaMCorrRel1( pCursorShell->GetTableCrs(), pOldNode, aNewPos, nCntIdx );
284 rDoc.cleanupUnoCursorTable();
285 for(const auto& pWeakUnoCursor : rDoc.mvUnoCursorTable)
287 auto pUnoCursor(pWeakUnoCursor.lock());
288 if(!pUnoCursor)
289 continue;
290 for(SwPaM& rPaM : pUnoCursor->GetRingContainer())
292 lcl_PaMCorrRel1( &rPaM, pOldNode, aNewPos, nCntIdx );
295 SwUnoTableCursor* pUnoTableCursor =
296 dynamic_cast<SwUnoTableCursor*>(pUnoCursor.get());
297 if( pUnoTableCursor )
299 for(SwPaM& rPaM : pUnoTableCursor->GetSelRing().GetRingContainer())
301 lcl_PaMCorrRel1( &rPaM, pOldNode, aNewPos, nCntIdx );
307 void SwDoc::CorrRel(const SwNode& rOldNode,
308 const SwPosition& rNewPos,
309 const sal_Int32 nOffset,
310 bool bMoveCursor)
312 getIDocumentMarkAccess()->correctMarksRelative(rOldNode, rNewPos, nOffset);
314 { // fix the Redlines
315 SwRedlineTable& rTable = getIDocumentRedlineAccess().GetRedlineTable();
316 SwPosition aNewPos(rNewPos);
317 for(SwRangeRedline* p : rTable)
319 // lies on the position ??
320 lcl_PaMCorrRel1( p, &rOldNode, aNewPos, aNewPos.GetContentIndex() + nOffset );
323 // To-Do - need to add here 'SwExtraRedlineTable' also ?
326 if(bMoveCursor)
327 ::PaMCorrRel(rOldNode, rNewPos, nOffset);
330 SwEditShell const * SwDoc::GetEditShell() const
332 SwViewShell const *pCurrentView = getIDocumentLayoutAccess().GetCurrentViewShell();
333 // Layout and OLE shells should be available
334 if( pCurrentView )
336 for(const SwViewShell& rCurrentSh : pCurrentView->GetRingContainer())
338 // look for an EditShell (if it exists)
339 if( auto pEditShell = dynamic_cast<const SwEditShell *>(&rCurrentSh) )
341 return pEditShell;
345 return nullptr;
348 SwEditShell* SwDoc::GetEditShell()
350 return const_cast<SwEditShell*>( const_cast<SwDoc const *>( this )->GetEditShell() );
353 ::sw::IShellCursorSupplier * SwDoc::GetIShellCursorSupplier()
355 return GetEditShell();
358 //bool foo()
360 // bool b1 = true ? true : false;
361 // bool b2 = (true ? true : false) ? true : false;
362 // bool b3 = true ? (true ? true : false) : false;
363 // bool b4 = true ? true : (true ? true : false);
364 // return false;
367 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */