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 .
22 #include <rootfrm.hxx>
26 #include <bookmrk.hxx>
27 #include <redline.hxx>
30 #include <unocrsr.hxx>
35 * Macros to iterate over all CrsrShells
37 #define PCURSH ((SwCrsrShell*)_pStartShell)
38 #define FOREACHSHELL_START( pEShell ) \
40 ViewShell *_pStartShell = pEShell; \
42 if( _pStartShell->IsA( TYPE( SwCrsrShell )) ) \
45 #define FOREACHSHELL_END( pEShell ) \
47 } while((_pStartShell=(ViewShell*)_pStartShell->GetNext())!= pEShell ); \
50 #define PCURCRSR (_pCurrCrsr)
51 #define FOREACHPAM_START(pSttCrsr) \
53 SwPaM *_pStartCrsr = pSttCrsr, *_pCurrCrsr = pSttCrsr; \
56 #define FOREACHPAM_END() \
57 } while( (_pCurrCrsr=(SwPaM *)_pCurrCrsr->GetNext()) != _pStartCrsr ); \
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();
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
))
88 static inline bool lcl_PaMCorrAbs(SwPaM
& rPam
,
89 const SwPosition
& rStart
,
90 const SwPosition
& rEnd
,
91 const SwPosition
& rNewPos
)
94 bRet
|= lcl_PosCorrAbs(rPam
.GetBound(true ), rStart
, rEnd
, rNewPos
);
95 bRet
|= lcl_PosCorrAbs(rPam
.GetBound(false), rStart
, rEnd
, rNewPos
);
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();
127 FOREACHSHELL_START( pShell
)
128 SwPaM
*_pStkCrsr
= PCURSH
->GetStkCrsr();
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
);
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
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
);
165 SwUnoTableCrsr
*const pUnoTblCrsr
=
166 dynamic_cast<SwUnoTableCrsr
*>(*it
);
169 FOREACHPAM_START( &pUnoTblCrsr
->GetSelRing() )
171 lcl_PaMCorrAbs( *PCURCRSR
, aStart
, aEnd
, aNewPos
);
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
,
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
);
200 SwRedlineTbl
& rTbl
= *mpRedlineTbl
;
201 for (sal_uInt16 n
= 0; n
< rTbl
.size(); )
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
);
222 ::PaMCorrAbs(aPam
, aNewPos
);
226 void SwDoc::CorrAbs(const SwPaM
& rRange
,
227 const SwPosition
& rNewPos
,
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
);
237 ::PaMCorrAbs(rRange
, rNewPos
);
240 void SwDoc::CorrAbs(const SwNodeIndex
& rStartNode
,
241 const SwNodeIndex
& rEndNode
,
242 const SwPosition
& rNewPos
,
245 _DelBookmarks(rStartNode
, rEndNode
);
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();
273 FOREACHSHELL_START( pShell
)
274 SwPaM
*_pStkCrsr
= PCURSH
->GetStkCrsr();
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
);
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
);
298 SwUnoTableCrsr
* pUnoTblCrsr
=
299 dynamic_cast<SwUnoTableCrsr
*>(*it
);
302 FOREACHPAM_START( &pUnoTblCrsr
->GetSelRing() )
303 lcl_PaMCorrRel1( PCURCRSR
, pOldNode
, aNewPos
, nCntIdx
);
310 void SwDoc::CorrRel(const SwNodeIndex
& rOldNode
,
311 const SwPosition
& rNewPos
,
312 const xub_StrLen nOffset
,
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
);
328 ::PaMCorrRel(rOldNode
, rNewPos
, nOffset
);
332 SwEditShell
* SwDoc::GetEditShell( ViewShell
** ppSh
) const
334 // Layout and OLE shells should be available
337 ViewShell
*pSh
= mpCurrentView
, *pVSh
= pSh
;
341 // look for an EditShell (if it exists)
343 if( pSh
->IsA( TYPE( SwEditShell
) ) )
344 return (SwEditShell
*)pSh
;
346 } while( pVSh
!= ( pSh
= (ViewShell
*)pSh
->GetNext() ));
349 *ppSh
= 0; //swmod 071029//swmod 071225
354 ::sw::IShellCursorSupplier
* SwDoc::GetIShellCursorSupplier()
356 return GetEditShell(0);
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */