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 .
21 #include <IDocumentLayoutAccess.hxx>
22 #include <IDocumentRedlineAccess.hxx>
26 #include <redline.hxx>
29 #include <unocrsr.hxx>
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();
49 bool lcl_PosCorrAbs(SwPosition
& rPos
,
50 const SwPosition
& rStart
,
51 const SwPosition
& rEnd
,
52 const SwPosition
& rNewPos
)
54 if ((rStart
<= rPos
) && (rPos
<= rEnd
))
62 bool lcl_PaMCorrAbs(SwPaM
& rPam
,
63 const SwPosition
& rStart
,
64 const SwPosition
& rEnd
,
65 const SwPosition
& rNewPos
)
68 bRet
|= lcl_PosCorrAbs(rPam
.GetBound(), rStart
, rEnd
, rNewPos
);
69 bRet
|= lcl_PosCorrAbs(rPam
.GetBound(false), rStart
, rEnd
, rNewPos
);
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
);
105 SwPaM
*_pStackCursor
= pCursorShell
->GetStackCursor();
109 lcl_PaMCorrAbs( *_pStackCursor
, aStart
, aEnd
, aNewPos
);
112 _pStackCursor
= _pStackCursor
->GetNext();
113 if( _pStackCursor
== pCursorShell
->GetStackCursor() )
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());
134 bool bChange
= false; // has the UNO cursor been corrected?
136 // determine whether the UNO cursor will leave it's designated
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())
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
,
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
);
185 SwRedlineTable
& rTable
= getIDocumentRedlineAccess().GetRedlineTable();
186 for (SwRedlineTable::size_type n
= 0; n
< rTable
.size(); )
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
);
204 // To-Do - need to add here 'SwExtraRedlineTable' also ?
209 ::PaMCorrAbs(aPam
, aNewPos
);
215 const SwPosition
& rNewPos
,
218 const SwPosition
& aStart(*rRange
.Start());
219 const SwPosition
& aEnd(*rRange
.End());
221 DelBookmarks( aStart
.GetNode(), aEnd
.GetNode(), nullptr, aStart
.GetContentIndex(), aEnd
.GetContentIndex() );
224 ::PaMCorrAbs(rRange
, rNewPos
);
228 const SwNodeIndex
& rStartNode
,
229 const SwNodeIndex
& rEndNode
,
230 const SwPosition
& rNewPos
,
233 DelBookmarks( rStartNode
.GetNode(), rEndNode
.GetNode() );
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
));
261 SwPaM
*_pStackCursor
= pCursorShell
->GetStackCursor();
265 lcl_PaMCorrRel1( _pStackCursor
, pOldNode
, aNewPos
, nCntIdx
);
268 _pStackCursor
= _pStackCursor
->GetNext();
269 if( _pStackCursor
== pCursorShell
->GetStackCursor() )
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());
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
,
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 ?
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
336 for(const SwViewShell
& rCurrentSh
: pCurrentView
->GetRingContainer())
338 // look for an EditShell (if it exists)
339 if( auto pEditShell
= dynamic_cast<const SwEditShell
*>(&rCurrentSh
) )
348 SwEditShell
* SwDoc::GetEditShell()
350 return const_cast<SwEditShell
*>( const_cast<SwDoc
const *>( this )->GetEditShell() );
353 ::sw::IShellCursorSupplier
* SwDoc::GetIShellCursorSupplier()
355 return GetEditShell();
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);
367 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */