Line data Source code
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>
21 : #include <IDocumentLayoutAccess.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 : {
38 : /// find the relevant section in which the SwUnoCrsr may wander.
39 : /// returns NULL if no restrictions apply
40 1956144 : static const SwStartNode* lcl_FindUnoCrsrSection( const SwNode& rNode )
41 : {
42 1956144 : const SwStartNode* pStartNode = rNode.StartOfSectionNode();
43 9764182 : while( ( pStartNode != NULL ) &&
44 5862859 : ( pStartNode->StartOfSectionNode() != pStartNode ) &&
45 1958840 : ( pStartNode->GetStartNodeType() == SwNormalStartNode ) )
46 1947875 : pStartNode = pStartNode->StartOfSectionNode();
47 :
48 1956144 : return pStartNode;
49 : }
50 :
51 1974958 : static inline bool lcl_PosCorrAbs(SwPosition & rPos,
52 : const SwPosition& rStart,
53 : const SwPosition& rEnd,
54 : const SwPosition& rNewPos)
55 : {
56 1974958 : if ((rStart <= rPos) && (rPos <= rEnd))
57 : {
58 19034 : rPos = rNewPos;
59 19034 : return true;
60 : }
61 1955924 : return false;
62 : };
63 :
64 987479 : static inline bool lcl_PaMCorrAbs(SwPaM & rPam,
65 : const SwPosition& rStart,
66 : const SwPosition& rEnd,
67 : const SwPosition& rNewPos)
68 : {
69 987479 : bool bRet = false;
70 987479 : bRet |= lcl_PosCorrAbs(rPam.GetBound(true ), rStart, rEnd, rNewPos);
71 987479 : bRet |= lcl_PosCorrAbs(rPam.GetBound(false), rStart, rEnd, rNewPos);
72 987479 : return bRet;
73 : };
74 :
75 13586 : static inline void lcl_PaMCorrRel1(SwPaM * pPam,
76 : SwNode const * const pOldNode,
77 : const SwPosition& rNewPos,
78 : const sal_Int32 nCntIdx)
79 : {
80 40758 : for(int nb = 0; nb < 2; ++nb)
81 27172 : if(&((pPam)->GetBound(bool(nb)).nNode.GetNode()) == pOldNode)
82 : {
83 5508 : (pPam)->GetBound(bool(nb)).nNode = rNewPos.nNode;
84 5508 : (pPam)->GetBound(bool(nb)).nContent.Assign(
85 5508 : const_cast<SwIndexReg*>(rNewPos.nContent.GetIdxReg()),
86 11016 : nCntIdx + (pPam)->GetBound(bool(nb)).nContent.GetIndex());
87 : }
88 13586 : }
89 : }
90 :
91 14190 : void PaMCorrAbs( const SwPaM& rRange,
92 : const SwPosition& rNewPos )
93 : {
94 14190 : SwPosition const aStart( *rRange.Start() );
95 28380 : SwPosition const aEnd( *rRange.End() );
96 28380 : SwPosition const aNewPos( rNewPos );
97 14190 : SwDoc *const pDoc = aStart.nNode.GetNode().GetDoc();
98 14190 : SwCrsrShell *const pShell = pDoc->GetEditShell();
99 :
100 14190 : if( pShell )
101 : {
102 2666 : for(const SwViewShell& rShell : pShell->GetRingContainer())
103 : {
104 1333 : if(!rShell.IsA( TYPE( SwCrsrShell )))
105 0 : continue;
106 1333 : const SwCrsrShell* pCrsrShell = static_cast<const SwCrsrShell*>(&rShell);
107 1333 : SwPaM *_pStkCrsr = pCrsrShell->GetStkCrsr();
108 1333 : if( _pStkCrsr )
109 3 : do {
110 3 : lcl_PaMCorrAbs( *_pStkCrsr, aStart, aEnd, aNewPos );
111 6 : } while ( (_pStkCrsr != 0 ) &&
112 3 : ((_pStkCrsr = static_cast<SwPaM *>(_pStkCrsr->GetNext())) != pCrsrShell->GetStkCrsr()) );
113 :
114 2666 : for(SwPaM& rPaM : const_cast<SwShellCrsr*>(pCrsrShell->_GetCrsr())->GetRingContainer())
115 : {
116 1333 : lcl_PaMCorrAbs( rPaM, aStart, aEnd, aNewPos );
117 : }
118 :
119 1333 : if( pCrsrShell->IsTableMode() )
120 0 : lcl_PaMCorrAbs( const_cast<SwPaM &>(*pCrsrShell->GetTableCrs()), aStart, aEnd, aNewPos );
121 : }
122 : }
123 : {
124 6422688 : for(auto pWeakUnoCrsr : pDoc->mvUnoCrsrTbl)
125 : {
126 7389632 : auto pUnoCursor(pWeakUnoCrsr.lock());
127 6408498 : if(!pUnoCursor)
128 5427364 : continue;
129 :
130 981134 : bool bChange = false; // has the UNO cursor been corrected?
131 :
132 : // determine whether the UNO cursor will leave it's designated
133 : // section
134 : bool const bLeaveSection =
135 1959206 : pUnoCursor->IsRemainInSection() &&
136 978072 : ( lcl_FindUnoCrsrSection( aNewPos.nNode.GetNode() ) !=
137 : lcl_FindUnoCrsrSection(
138 1959206 : pUnoCursor->GetPoint()->nNode.GetNode() ) );
139 :
140 1962268 : for(SwPaM& rPaM : pUnoCursor->GetRingContainer())
141 : {
142 981134 : bChange |= lcl_PaMCorrAbs( rPaM, aStart, aEnd, aNewPos );
143 : }
144 :
145 : SwUnoTableCrsr *const pUnoTblCrsr =
146 981134 : dynamic_cast<SwUnoTableCrsr *>(pUnoCursor.get());
147 981134 : if( pUnoTblCrsr )
148 : {
149 2318 : for(SwPaM& rPaM : (&pUnoTblCrsr->GetSelRing())->GetRingContainer())
150 : {
151 : bChange |=
152 2153 : lcl_PaMCorrAbs( rPaM, aStart, aEnd, aNewPos );
153 : }
154 : }
155 :
156 : // if a UNO cursor leaves its designated section, we must inform
157 : // (and invalidate) said cursor
158 981134 : if (bChange && bLeaveSection)
159 : {
160 : // the UNO cursor has left its section. We need to notify it!
161 1507 : SwMsgPoolItem aHint( RES_UNOCURSOR_LEAVES_SECTION );
162 1507 : pUnoCursor->ModifyNotification( &aHint, NULL );
163 : }
164 981134 : }
165 14190 : }
166 14190 : }
167 :
168 2962 : void SwDoc::CorrAbs(const SwNodeIndex& rOldNode,
169 : const SwPosition& rNewPos,
170 : const sal_Int32 nOffset,
171 : bool bMoveCrsr)
172 : {
173 2962 : SwContentNode *const pContentNode( rOldNode.GetNode().GetContentNode() );
174 : SwPaM const aPam(rOldNode, 0,
175 2962 : rOldNode, (pContentNode) ? pContentNode->Len() : 0);
176 5924 : SwPosition aNewPos(rNewPos);
177 2962 : aNewPos.nContent += nOffset;
178 :
179 2962 : getIDocumentMarkAccess()->correctMarksAbsolute(rOldNode, rNewPos, nOffset);
180 : // fix redlines
181 : {
182 2962 : SwRedlineTable& rTable = getIDocumentRedlineAccess().GetRedlineTable();
183 8780 : for (SwRedlineTable::size_type n = 0; n < rTable.size(); )
184 : {
185 : // is on position ??
186 2856 : SwRangeRedline *const pRedline( rTable[ n ] );
187 : bool const bChanged =
188 2856 : lcl_PaMCorrAbs(*pRedline, *aPam.Start(), *aPam.End(), aNewPos);
189 : // clean up empty redlines: docredln.cxx asserts these as invalid
190 2856 : if (bChanged && (*pRedline->GetPoint() == *pRedline->GetMark())
191 2856 : && (pRedline->GetContentIdx() == NULL))
192 : {
193 0 : rTable.DeleteAndDestroy(n);
194 : }
195 : else
196 : {
197 2856 : ++n;
198 : }
199 : }
200 :
201 : // To-Do - need to add here 'SwExtraRedlineTable' also ?
202 : }
203 :
204 2962 : if(bMoveCrsr)
205 : {
206 2962 : ::PaMCorrAbs(aPam, aNewPos);
207 2962 : }
208 2962 : }
209 :
210 3 : void SwDoc::CorrAbs(
211 : const SwPaM& rRange,
212 : const SwPosition& rNewPos,
213 : bool bMoveCrsr )
214 : {
215 3 : SwPosition aStart(*rRange.Start());
216 6 : SwPosition aEnd(*rRange.End());
217 6 : SwPosition aNewPos(rNewPos);
218 :
219 3 : _DelBookmarks( aStart.nNode, aEnd.nNode, NULL, &aStart.nContent, &aEnd.nContent );
220 :
221 3 : if(bMoveCrsr)
222 6 : ::PaMCorrAbs(rRange, rNewPos);
223 3 : }
224 :
225 4872 : void SwDoc::CorrAbs(
226 : const SwNodeIndex& rStartNode,
227 : const SwNodeIndex& rEndNode,
228 : const SwPosition& rNewPos,
229 : bool bMoveCrsr )
230 : {
231 4872 : _DelBookmarks( rStartNode, rEndNode );
232 :
233 4872 : if(bMoveCrsr)
234 : {
235 4872 : SwContentNode *const pContentNode( rEndNode.GetNode().GetContentNode() );
236 : SwPaM const aPam(rStartNode, 0,
237 4872 : rEndNode, (pContentNode) ? pContentNode->Len() : 0);
238 4872 : ::PaMCorrAbs(aPam, rNewPos);
239 : }
240 4872 : }
241 :
242 2830 : void PaMCorrRel( const SwNodeIndex &rOldNode,
243 : const SwPosition &rNewPos,
244 : const sal_Int32 nOffset )
245 : {
246 2830 : const SwNode* pOldNode = &rOldNode.GetNode();
247 2830 : SwPosition aNewPos( rNewPos );
248 2830 : const SwDoc* pDoc = pOldNode->GetDoc();
249 :
250 2830 : const sal_Int32 nCntIdx = rNewPos.nContent.GetIndex() + nOffset;
251 :
252 2830 : SwCrsrShell const* pShell = pDoc->GetEditShell();
253 2830 : if( pShell )
254 : {
255 46 : for(const SwViewShell& rShell : pShell->GetRingContainer())
256 : {
257 23 : if(!rShell.IsA( TYPE( SwCrsrShell )))
258 0 : continue;
259 23 : SwCrsrShell* pCrsrShell = const_cast<SwCrsrShell*>(static_cast<const SwCrsrShell*>(&rShell));
260 23 : SwPaM *_pStkCrsr = pCrsrShell->GetStkCrsr();
261 23 : if( _pStkCrsr )
262 0 : do {
263 0 : lcl_PaMCorrRel1( _pStkCrsr, pOldNode, aNewPos, nCntIdx );
264 0 : } while ( (_pStkCrsr != 0 ) &&
265 0 : ((_pStkCrsr = static_cast<SwPaM *>(_pStkCrsr->GetNext())) != pCrsrShell->GetStkCrsr()) );
266 :
267 23 : SwPaM* pStartPaM = pCrsrShell->_GetCrsr();
268 46 : for(SwPaM& rPaM : pStartPaM->GetRingContainer())
269 : {
270 23 : lcl_PaMCorrRel1( &rPaM, pOldNode, aNewPos, nCntIdx);
271 : }
272 :
273 23 : if( pCrsrShell->IsTableMode() )
274 0 : lcl_PaMCorrRel1( pCrsrShell->GetTableCrs(), pOldNode, aNewPos, nCntIdx );
275 : }
276 : }
277 : {
278 566269 : for(auto pWeakUnoCrsr : pDoc->mvUnoCrsrTbl)
279 : {
280 575616 : auto pUnoCrsr(pWeakUnoCrsr.lock());
281 563439 : if(!pUnoCrsr)
282 551262 : continue;
283 24354 : for(SwPaM& rPaM : pUnoCrsr->GetRingContainer())
284 : {
285 12177 : lcl_PaMCorrRel1( &rPaM, pOldNode, aNewPos, nCntIdx );
286 : }
287 :
288 : SwUnoTableCrsr* pUnoTblCrsr =
289 12177 : dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr.get());
290 12177 : if( pUnoTblCrsr )
291 : {
292 0 : for(SwPaM& rPaM : (&pUnoTblCrsr->GetSelRing())->GetRingContainer())
293 : {
294 0 : lcl_PaMCorrRel1( &rPaM, pOldNode, aNewPos, nCntIdx );
295 : }
296 : }
297 12177 : }
298 2830 : }
299 2830 : }
300 :
301 2830 : void SwDoc::CorrRel(const SwNodeIndex& rOldNode,
302 : const SwPosition& rNewPos,
303 : const sal_Int32 nOffset,
304 : bool bMoveCrsr)
305 : {
306 2830 : getIDocumentMarkAccess()->correctMarksRelative(rOldNode, rNewPos, nOffset);
307 :
308 : { // fix the Redlines
309 2830 : SwRedlineTable& rTable = getIDocumentRedlineAccess().GetRedlineTable();
310 2830 : SwPosition aNewPos(rNewPos);
311 4216 : for( SwRedlineTable::size_type n = 0; n < rTable.size(); ++n )
312 : {
313 : // lies on the position ??
314 1386 : lcl_PaMCorrRel1( rTable[ n ], &rOldNode.GetNode(), aNewPos, aNewPos.nContent.GetIndex() + nOffset );
315 2830 : }
316 :
317 : // To-Do - need to add here 'SwExtraRedlineTable' also ?
318 : }
319 :
320 2830 : if(bMoveCrsr)
321 2830 : ::PaMCorrRel(rOldNode, rNewPos, nOffset);
322 2830 : }
323 :
324 76142 : SwEditShell const * SwDoc::GetEditShell() const
325 : {
326 76142 : SwViewShell const *pCurrentView = getIDocumentLayoutAccess().GetCurrentViewShell();
327 : // Layout and OLE shells should be available
328 76142 : if( pCurrentView )
329 : {
330 8577 : for(const SwViewShell& rCurrentSh : pCurrentView->GetRingContainer())
331 : {
332 : // look for an EditShell (if it exists)
333 8577 : if( rCurrentSh.IsA( TYPE( SwEditShell ) ) )
334 : {
335 8577 : return static_cast<const SwEditShell*>(&rCurrentSh);
336 : }
337 : }
338 : }
339 67565 : return nullptr;
340 : }
341 :
342 73248 : SwEditShell* SwDoc::GetEditShell()
343 : {
344 73248 : return const_cast<SwEditShell*>( const_cast<SwDoc const *>( this )->GetEditShell() );
345 : }
346 :
347 1 : ::sw::IShellCursorSupplier * SwDoc::GetIShellCursorSupplier()
348 : {
349 1 : return GetEditShell();
350 177 : }
351 :
352 : //bool foo()
353 : //{
354 : // bool b1 = true ? true : false;
355 : // bool b2 = (true ? true : false) ? true : false;
356 : // bool b3 = true ? (true ? true : false) : false;
357 : // bool b4 = true ? true : (true ? true : false);
358 : // return false;
359 : //}
360 :
361 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|