update credits
[LibreOffice.git] / sw / source / core / doc / doccorr.cxx
blob392524a3a76c18a26716248bfe0cb5a3a1fb1e79
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 <node.hxx>
22 #include <rootfrm.hxx>
23 #include <editsh.hxx>
24 #include <viscrs.hxx>
25 #include <IMark.hxx>
26 #include <bookmrk.hxx>
27 #include <redline.hxx>
28 #include <mvsave.hxx>
29 #include <docary.hxx>
30 #include <unocrsr.hxx>
31 #include <swundo.hxx>
32 #include <hints.hxx>
35 * Macros to iterate over all CrsrShells
37 #define PCURSH ((SwCrsrShell*)_pStartShell)
38 #define FOREACHSHELL_START( pEShell ) \
40 ViewShell *_pStartShell = pEShell; \
41 do { \
42 if( _pStartShell->IsA( TYPE( SwCrsrShell )) ) \
45 #define FOREACHSHELL_END( pEShell ) \
46 } \
47 } while((_pStartShell=(ViewShell*)_pStartShell->GetNext())!= pEShell ); \
50 #define PCURCRSR (_pCurrCrsr)
51 #define FOREACHPAM_START(pSttCrsr) \
53 SwPaM *_pStartCrsr = pSttCrsr, *_pCurrCrsr = pSttCrsr; \
54 do {
56 #define FOREACHPAM_END() \
57 } while( (_pCurrCrsr=(SwPaM *)_pCurrCrsr->GetNext()) != _pStartCrsr ); \
60 namespace
62 /// find the relevant section in which the SwUnoCrsr may wander.
63 /// returns NULL if no restrictions apply
64 static const SwStartNode* lcl_FindUnoCrsrSection( const SwNode& rNode )
66 const SwStartNode* pStartNode = rNode.StartOfSectionNode();
67 while( ( pStartNode != NULL ) &&
68 ( pStartNode->StartOfSectionNode() != pStartNode ) &&
69 ( pStartNode->GetStartNodeType() == SwNormalStartNode ) )
70 pStartNode = pStartNode->StartOfSectionNode();
72 return pStartNode;
75 static inline bool lcl_PosCorrAbs(SwPosition & rPos,
76 const SwPosition& rStart,
77 const SwPosition& rEnd,
78 const SwPosition& rNewPos)
80 if ((rStart <= rPos) && (rPos <= rEnd))
82 rPos = rNewPos;
83 return true;
85 return false;
88 static inline bool lcl_PaMCorrAbs(SwPaM & rPam,
89 const SwPosition& rStart,
90 const SwPosition& rEnd,
91 const SwPosition& rNewPos)
93 bool bRet = false;
94 bRet |= lcl_PosCorrAbs(rPam.GetBound(true ), rStart, rEnd, rNewPos);
95 bRet |= lcl_PosCorrAbs(rPam.GetBound(false), rStart, rEnd, rNewPos);
96 return bRet;
99 static inline void lcl_PaMCorrRel1(SwPaM * pPam,
100 SwNode const * const pOldNode,
101 const SwPosition& rNewPos,
102 const xub_StrLen nCntIdx)
104 for(int nb = 0; nb < 2; ++nb)
105 if(&((pPam)->GetBound(sal_Bool(nb)).nNode.GetNode()) == pOldNode)
107 (pPam)->GetBound(sal_Bool(nb)).nNode = rNewPos.nNode;
108 (pPam)->GetBound(sal_Bool(nb)).nContent.Assign(
109 const_cast<SwIndexReg*>(rNewPos.nContent.GetIdxReg()),
110 nCntIdx + (pPam)->GetBound(sal_Bool(nb)).nContent.GetIndex());
116 void PaMCorrAbs( const SwPaM& rRange,
117 const SwPosition& rNewPos )
119 SwPosition const aStart( *rRange.Start() );
120 SwPosition const aEnd( *rRange.End() );
121 SwPosition const aNewPos( rNewPos );
122 SwDoc *const pDoc = aStart.nNode.GetNode().GetDoc();
123 SwCrsrShell *const pShell = pDoc->GetEditShell();
125 if( pShell )
127 FOREACHSHELL_START( pShell )
128 SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
129 if( _pStkCrsr )
130 do {
131 lcl_PaMCorrAbs( *_pStkCrsr, aStart, aEnd, aNewPos );
132 } while ( (_pStkCrsr != 0 ) &&
133 ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );
135 FOREACHPAM_START( PCURSH->_GetCrsr() )
136 lcl_PaMCorrAbs( *PCURCRSR, aStart, aEnd, aNewPos );
137 FOREACHPAM_END()
139 if( PCURSH->IsTableMode() )
140 lcl_PaMCorrAbs( *PCURSH->GetTblCrs(), aStart, aEnd, aNewPos );
142 FOREACHSHELL_END( pShell )
145 SwUnoCrsrTbl& rTbl = const_cast<SwUnoCrsrTbl&>(pDoc->GetUnoCrsrTbl());
147 for( SwUnoCrsrTbl::iterator it = rTbl.begin(); it != rTbl.end(); ++it )
149 SwUnoCrsr *const pUnoCursor = *it;
151 bool bChange = false; // has the UNO cursor been corrected?
153 // determine whether the UNO cursor will leave it's designated
154 // section
155 bool const bLeaveSection =
156 pUnoCursor->IsRemainInSection() &&
157 ( lcl_FindUnoCrsrSection( aNewPos.nNode.GetNode() ) !=
158 lcl_FindUnoCrsrSection(
159 pUnoCursor->GetPoint()->nNode.GetNode() ) );
161 FOREACHPAM_START( pUnoCursor )
162 bChange |= lcl_PaMCorrAbs( *PCURCRSR, aStart, aEnd, aNewPos );
163 FOREACHPAM_END()
165 SwUnoTableCrsr *const pUnoTblCrsr =
166 dynamic_cast<SwUnoTableCrsr *>(*it);
167 if( pUnoTblCrsr )
169 FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
170 bChange |=
171 lcl_PaMCorrAbs( *PCURCRSR, aStart, aEnd, aNewPos );
172 FOREACHPAM_END()
175 // if a UNO cursor leaves its designated section, we must inform
176 // (and invalidate) said cursor
177 if (bChange && bLeaveSection)
179 // the UNO cursor has left its section. We need to notify it!
180 SwMsgPoolItem aHint( RES_UNOCURSOR_LEAVES_SECTION );
181 pUnoCursor->ModifyNotification( &aHint, NULL );
187 void SwDoc::CorrAbs(const SwNodeIndex& rOldNode,
188 const SwPosition& rNewPos,
189 const xub_StrLen nOffset,
190 sal_Bool bMoveCrsr)
192 SwCntntNode *const pCntntNode( rOldNode.GetNode().GetCntntNode() );
193 SwPaM const aPam(rOldNode, 0,
194 rOldNode, (pCntntNode) ? pCntntNode->Len() : 0);
195 SwPosition aNewPos(rNewPos);
196 aNewPos.nContent += nOffset;
198 getIDocumentMarkAccess()->correctMarksAbsolute(rOldNode, rNewPos, nOffset);
199 { // fix redlines
200 SwRedlineTbl& rTbl = *mpRedlineTbl;
201 for (sal_uInt16 n = 0; n < rTbl.size(); )
203 // is on position ??
204 SwRedline *const pRedline( rTbl[ n ] );
205 bool const bChanged =
206 lcl_PaMCorrAbs(*pRedline, *aPam.Start(), *aPam.End(), aNewPos);
207 // clean up empty redlines: docredln.cxx asserts these as invalid
208 if (bChanged && (*pRedline->GetPoint() == *pRedline->GetMark())
209 && (pRedline->GetContentIdx() == NULL))
211 rTbl.DeleteAndDestroy(n);
213 else
215 ++n;
220 if(bMoveCrsr)
222 ::PaMCorrAbs(aPam, aNewPos);
226 void SwDoc::CorrAbs(const SwPaM& rRange,
227 const SwPosition& rNewPos,
228 sal_Bool bMoveCrsr)
230 SwPosition aStart(*rRange.Start());
231 SwPosition aEnd(*rRange.End());
232 SwPosition aNewPos(rNewPos);
234 _DelBookmarks(aStart.nNode, aEnd.nNode, NULL,
235 &aStart.nContent, &aEnd.nContent);
236 if(bMoveCrsr)
237 ::PaMCorrAbs(rRange, rNewPos);
240 void SwDoc::CorrAbs(const SwNodeIndex& rStartNode,
241 const SwNodeIndex& rEndNode,
242 const SwPosition& rNewPos,
243 sal_Bool bMoveCrsr)
245 _DelBookmarks(rStartNode, rEndNode);
247 if(bMoveCrsr)
249 SwCntntNode *const pCntntNode( rEndNode.GetNode().GetCntntNode() );
250 SwPaM const aPam(rStartNode, 0,
251 rEndNode, (pCntntNode) ? pCntntNode->Len() : 0);
252 ::PaMCorrAbs(aPam, rNewPos);
260 void PaMCorrRel( const SwNodeIndex &rOldNode,
261 const SwPosition &rNewPos,
262 const xub_StrLen nOffset )
264 const SwNode* pOldNode = &rOldNode.GetNode();
265 SwPosition aNewPos( rNewPos );
266 const SwDoc* pDoc = pOldNode->GetDoc();
268 xub_StrLen nCntIdx = rNewPos.nContent.GetIndex() + nOffset;
270 SwCrsrShell* pShell = pDoc->GetEditShell();
271 if( pShell )
273 FOREACHSHELL_START( pShell )
274 SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
275 if( _pStkCrsr )
276 do {
277 lcl_PaMCorrRel1( _pStkCrsr, pOldNode, aNewPos, nCntIdx );
278 } while ( (_pStkCrsr != 0 ) &&
279 ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );
281 FOREACHPAM_START( PCURSH->_GetCrsr() )
282 lcl_PaMCorrRel1( PCURCRSR, pOldNode, aNewPos, nCntIdx);
283 FOREACHPAM_END()
285 if( PCURSH->IsTableMode() )
286 lcl_PaMCorrRel1( PCURSH->GetTblCrs(), pOldNode, aNewPos, nCntIdx );
288 FOREACHSHELL_END( pShell )
291 SwUnoCrsrTbl& rTbl = (SwUnoCrsrTbl&)pDoc->GetUnoCrsrTbl();
292 for( SwUnoCrsrTbl::iterator it = rTbl.begin(); it != rTbl.end(); ++it )
294 FOREACHPAM_START( *it )
295 lcl_PaMCorrRel1( PCURCRSR, pOldNode, aNewPos, nCntIdx );
296 FOREACHPAM_END()
298 SwUnoTableCrsr* pUnoTblCrsr =
299 dynamic_cast<SwUnoTableCrsr*>(*it);
300 if( pUnoTblCrsr )
302 FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
303 lcl_PaMCorrRel1( PCURCRSR, pOldNode, aNewPos, nCntIdx );
304 FOREACHPAM_END()
310 void SwDoc::CorrRel(const SwNodeIndex& rOldNode,
311 const SwPosition& rNewPos,
312 const xub_StrLen nOffset,
313 sal_Bool bMoveCrsr)
315 getIDocumentMarkAccess()->correctMarksRelative(rOldNode, rNewPos, nOffset);
317 { // fix the Redlines
318 SwRedlineTbl& rTbl = *mpRedlineTbl;
319 SwPosition aNewPos(rNewPos);
320 for( sal_uInt16 n = 0; n < rTbl.size(); ++n )
322 // lies on the position ??
323 lcl_PaMCorrRel1( rTbl[ n ], &rOldNode.GetNode(), aNewPos, aNewPos.nContent.GetIndex() + nOffset );
327 if(bMoveCrsr)
328 ::PaMCorrRel(rOldNode, rNewPos, nOffset);
332 SwEditShell* SwDoc::GetEditShell( ViewShell** ppSh ) const
334 // Layout and OLE shells should be available
335 if( mpCurrentView )
337 ViewShell *pSh = mpCurrentView, *pVSh = pSh;
338 if( ppSh )
339 *ppSh = pSh;
341 // look for an EditShell (if it exists)
342 do {
343 if( pSh->IsA( TYPE( SwEditShell ) ) )
344 return (SwEditShell*)pSh;
346 } while( pVSh != ( pSh = (ViewShell*)pSh->GetNext() ));
348 else if( ppSh )
349 *ppSh = 0; //swmod 071029//swmod 071225
351 return 0;
354 ::sw::IShellCursorSupplier * SwDoc::GetIShellCursorSupplier()
356 return GetEditShell(0);
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */