1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: doccorr.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
37 #include <rootfrm.hxx>
41 #include <bookmrk.hxx>
42 #include <redline.hxx>
45 #include <unocrsr.hxx>
52 * MACROS um ueber alle CrsrShells zu iterieren
54 #define PCURSH ((SwCrsrShell*)_pStartShell)
55 #define FOREACHSHELL_START( pEShell ) \
57 ViewShell *_pStartShell = pEShell; \
59 if( _pStartShell->IsA( TYPE( SwCrsrShell )) ) \
62 #define FOREACHSHELL_END( pEShell ) \
64 } while((_pStartShell=(ViewShell*)_pStartShell->GetNext())!= pEShell ); \
67 #define PCURCRSR (_pCurrCrsr)
68 #define FOREACHPAM_START(pSttCrsr) \
70 SwPaM *_pStartCrsr = pSttCrsr, *_pCurrCrsr = pSttCrsr; \
73 #define FOREACHPAM_END() \
74 } while( (_pCurrCrsr=(SwPaM *)_pCurrCrsr->GetNext()) != _pStartCrsr ); \
79 // find the relevant section in which the SwUnoCrsr may wander. returns NULL if
80 // no restrictions apply
81 const SwStartNode
* lcl_FindUnoCrsrSection( const SwNode
& rNode
)
83 const SwStartNode
* pStartNode
= rNode
.StartOfSectionNode();
84 while( ( pStartNode
!= NULL
) &&
85 ( pStartNode
->StartOfSectionNode() != pStartNode
) &&
86 ( pStartNode
->GetStartNodeType() == SwNormalStartNode
) )
87 pStartNode
= pStartNode
->StartOfSectionNode();
92 static inline void lcl_PaMCorrAbs1(SwPaM
* pPam
,
93 SwNode
const * const pOldNode
,
94 const SwPosition
& rNewPos
,
95 const xub_StrLen nOffset
)
97 for(int nb
= 0; nb
< 2; ++nb
)
98 if(&((pPam
)->GetBound(BOOL(nb
)).nNode
.GetNode()) == pOldNode
)
100 (pPam
)->GetBound(BOOL(nb
)) = rNewPos
;
101 (pPam
)->GetBound(BOOL(nb
)).nContent
+= nOffset
;
105 static inline bool lcl_PaMCorrAbs2(SwPaM
* pPam
,
106 const SwPosition
& rNewPos
,
112 for(int nb
= 0; nb
< 2; ++nb
)
113 if((pPam
)->GetBound(BOOL(nb
)).nNode
>= nSttNode
&&
114 (pPam
)->GetBound(BOOL(nb
)).nNode
<= nEndNode
)
116 (pPam
)->GetBound(BOOL(nb
)) = rNewPos
;
122 static inline void lcl_PaMCorrAbs3(SwPaM
* pPam
,
123 const SwPosition
& rStart
,
124 const SwPosition
& rEnd
,
125 const SwPosition
& rNewPos
)
127 for(int nb
= 0; nb
< 2; ++nb
)
128 if(rStart
<= (pPam
)->GetBound(BOOL(nb
)) &&
129 (pPam
)->GetBound(BOOL(nb
)) <= rEnd
)
130 (pPam
)->GetBound(BOOL(nb
)) = rNewPos
;
133 static inline void lcl_PaMCorrRel1(SwPaM
* pPam
,
134 SwNode
const * const pOldNode
,
135 const SwPosition
& rNewPos
,
136 const xub_StrLen nCntIdx
)
138 for(int nb
= 0; nb
< 2; ++nb
)
139 if(&((pPam
)->GetBound(BOOL(nb
)).nNode
.GetNode()) == pOldNode
)
141 (pPam
)->GetBound(BOOL(nb
)).nNode
= rNewPos
.nNode
;
142 (pPam
)->GetBound(BOOL(nb
)).nContent
.Assign(
143 const_cast<SwIndexReg
*>(rNewPos
.nContent
.GetIdxReg()),
144 nCntIdx
+ (pPam
)->GetBound(BOOL(nb
)).nContent
.GetIndex());
149 void PaMCorrAbs( const SwNodeIndex
&rOldNode
,
150 const SwPosition
&rNewPos
,
151 const xub_StrLen nOffset
)
153 const SwNode
* pOldNode
= &rOldNode
.GetNode();
154 const SwPosition
aNewPos( rNewPos
);
155 const SwDoc
* pDoc
= pOldNode
->GetDoc();
156 SwCrsrShell
* pShell
= pDoc
->GetEditShell();
160 FOREACHSHELL_START( pShell
)
161 SwPaM
*_pStkCrsr
= PCURSH
->GetStkCrsr();
164 lcl_PaMCorrAbs1( _pStkCrsr
, pOldNode
, aNewPos
, nOffset
);
165 } while ( (_pStkCrsr
!= 0 ) &&
166 ((_pStkCrsr
=(SwPaM
*)_pStkCrsr
->GetNext()) != PCURSH
->GetStkCrsr()) );
168 FOREACHPAM_START( PCURSH
->_GetCrsr() )
169 lcl_PaMCorrAbs1( PCURCRSR
, pOldNode
, aNewPos
, nOffset
);
172 if( PCURSH
->IsTableMode() )
173 lcl_PaMCorrAbs1( PCURSH
->GetTblCrs(), pOldNode
, aNewPos
, nOffset
);
175 FOREACHSHELL_END( pShell
)
179 SwUnoCrsrTbl
& rTbl
= (SwUnoCrsrTbl
&)pDoc
->GetUnoCrsrTbl();
180 for( USHORT n
= 0; n
< rTbl
.Count(); ++n
)
182 FOREACHPAM_START( rTbl
[ n
] )
183 lcl_PaMCorrAbs1( PCURCRSR
, pOldNode
, aNewPos
, nOffset
);
186 SwUnoTableCrsr
* pUnoTblCrsr
=
187 dynamic_cast<SwUnoTableCrsr
*>(rTbl
[ n
]);
190 FOREACHPAM_START( &pUnoTblCrsr
->GetSelRing() )
191 lcl_PaMCorrAbs1( PCURCRSR
, pOldNode
, aNewPos
, nOffset
);
199 void PaMCorrAbs( const SwNodeIndex
&rStartNode
,
200 const SwNodeIndex
&rEndNode
,
201 const SwPosition
&rNewPos
)
203 const ULONG nSttNode
= rStartNode
.GetIndex();
204 const ULONG nEndNode
= rEndNode
.GetIndex();
205 const SwPosition
aNewPos( rNewPos
);
206 SwDoc
* pDoc
= rStartNode
.GetNode().GetDoc();
208 SwCrsrShell
* pShell
= pDoc
->GetEditShell();
211 FOREACHSHELL_START( pShell
)
212 SwPaM
*_pStkCrsr
= PCURSH
->GetStkCrsr();
215 lcl_PaMCorrAbs2( _pStkCrsr
, aNewPos
, nSttNode
, nEndNode
);
216 } while ( (_pStkCrsr
!= 0 ) &&
217 ((_pStkCrsr
=(SwPaM
*)_pStkCrsr
->GetNext()) != PCURSH
->GetStkCrsr()) );
219 FOREACHPAM_START( PCURSH
->_GetCrsr() )
220 lcl_PaMCorrAbs2( PCURCRSR
, aNewPos
, nSttNode
, nEndNode
);
223 if( PCURSH
->IsTableMode() )
224 lcl_PaMCorrAbs2( PCURSH
->GetTblCrs(), aNewPos
, nSttNode
, nEndNode
);
226 FOREACHSHELL_END( pShell
)
230 SwUnoCrsrTbl
& rTbl
= (SwUnoCrsrTbl
&)pDoc
->GetUnoCrsrTbl();
231 for( USHORT n
= 0; n
< rTbl
.Count(); ++n
)
233 bool bChange
= false;
235 SwUnoCrsr
* pUnoCursor
= rTbl
[ n
];
237 // determine whether the UNO cursor will leave it's designated
240 pUnoCursor
->IsRemainInSection() &&
241 ( lcl_FindUnoCrsrSection( aNewPos
.nNode
.GetNode() ) !=
242 lcl_FindUnoCrsrSection(
243 pUnoCursor
->GetPoint()->nNode
.GetNode() ) );
245 FOREACHPAM_START( pUnoCursor
)
246 bChange
|= lcl_PaMCorrAbs2(PCURCRSR
, aNewPos
, nSttNode
, nEndNode
);
249 SwUnoTableCrsr
* pUnoTblCrsr
=
250 dynamic_cast<SwUnoTableCrsr
*>(pUnoCursor
);
253 FOREACHPAM_START( &pUnoTblCrsr
->GetSelRing() )
255 lcl_PaMCorrAbs2( PCURCRSR
, aNewPos
, nSttNode
, nEndNode
);
259 // if a UNO cursor leaves its designated section, we must inform
260 // (and invalidate) said cursor
261 if( bChange
&& bLeaveSection
)
263 // the UNO cursor has left its section. We need to notify it!
264 SwMsgPoolItem
aHint( RES_UNOCURSOR_LEAVES_SECTION
);
265 pUnoCursor
->Modify( &aHint
, NULL
);
272 void PaMCorrAbs( const SwPaM
& rRange
,
273 const SwPosition
& rNewPos
)
275 SwPosition
aStart( *rRange
.Start() );
276 SwPosition
aEnd( *rRange
.End() );
277 SwPosition
aNewPos( rNewPos
);
278 SwDoc
* pDoc
= aStart
.nNode
.GetNode().GetDoc();
279 SwCrsrShell
* pShell
= pDoc
->GetEditShell();
283 FOREACHSHELL_START( pShell
)
284 SwPaM
*_pStkCrsr
= PCURSH
->GetStkCrsr();
287 lcl_PaMCorrAbs3( _pStkCrsr
, aStart
, aEnd
, aNewPos
);
288 } while ( (_pStkCrsr
!= 0 ) &&
289 ((_pStkCrsr
=(SwPaM
*)_pStkCrsr
->GetNext()) != PCURSH
->GetStkCrsr()) );
291 FOREACHPAM_START( PCURSH
->_GetCrsr() )
292 lcl_PaMCorrAbs3( PCURCRSR
, aStart
, aEnd
, aNewPos
);
295 if( PCURSH
->IsTableMode() )
296 lcl_PaMCorrAbs3( PCURSH
->GetTblCrs(), aStart
, aEnd
, aNewPos
);
298 FOREACHSHELL_END( pShell
)
301 SwUnoCrsrTbl
& rTbl
= (SwUnoCrsrTbl
&)pDoc
->GetUnoCrsrTbl();
302 for( USHORT n
= 0; n
< rTbl
.Count(); ++n
)
304 FOREACHPAM_START( rTbl
[ n
] )
305 lcl_PaMCorrAbs3( PCURCRSR
, aStart
, aEnd
, aNewPos
);
308 SwUnoTableCrsr
* pUnoTblCrsr
=
309 dynamic_cast<SwUnoTableCrsr
*>(rTbl
[ n
]);
312 FOREACHPAM_START( &pUnoTblCrsr
->GetSelRing() )
313 lcl_PaMCorrAbs3( PCURCRSR
, aStart
, aEnd
, aNewPos
);
320 void SwDoc::CorrAbs(const SwNodeIndex
& rOldNode
,
321 const SwPosition
& rNewPos
,
322 const xub_StrLen nOffset
,
325 getIDocumentMarkAccess()->correctMarksAbsolute(rOldNode
, rNewPos
, nOffset
);
327 SwRedlineTbl
& rTbl
= *pRedlineTbl
;
328 for( USHORT n
= 0; n
< rTbl
.Count(); ++n
)
331 lcl_PaMCorrAbs1( rTbl
[ n
], &rOldNode
.GetNode(), SwPosition(rNewPos
), nOffset
);
336 ::PaMCorrAbs(rOldNode
, rNewPos
, nOffset
);
339 void SwDoc::CorrAbs(const SwPaM
& rRange
,
340 const SwPosition
& rNewPos
,
343 SwPosition
aStart(*rRange
.Start());
344 SwPosition
aEnd(*rRange
.End());
345 SwPosition
aNewPos(rNewPos
);
347 _DelBookmarks(aStart
.nNode
, aEnd
.nNode
, NULL
,
348 &aStart
.nContent
, &aEnd
.nContent
);
350 ::PaMCorrAbs(rRange
, rNewPos
);
353 void SwDoc::CorrAbs(const SwNodeIndex
& rStartNode
,
354 const SwNodeIndex
& rEndNode
,
355 const SwPosition
& rNewPos
,
358 SwPosition
aNewPos(rNewPos
);
360 _DelBookmarks(rStartNode
, rEndNode
);
363 ::PaMCorrAbs(rStartNode
, rEndNode
, rNewPos
);
370 void PaMCorrRel( const SwNodeIndex
&rOldNode
,
371 const SwPosition
&rNewPos
,
372 const xub_StrLen nOffset
)
374 const SwNode
* pOldNode
= &rOldNode
.GetNode();
375 SwPosition
aNewPos( rNewPos
);
376 const SwDoc
* pDoc
= pOldNode
->GetDoc();
378 xub_StrLen nCntIdx
= rNewPos
.nContent
.GetIndex() + nOffset
;
380 SwCrsrShell
* pShell
= pDoc
->GetEditShell();
383 FOREACHSHELL_START( pShell
)
384 SwPaM
*_pStkCrsr
= PCURSH
->GetStkCrsr();
387 lcl_PaMCorrRel1( _pStkCrsr
, pOldNode
, aNewPos
, nCntIdx
);
388 } while ( (_pStkCrsr
!= 0 ) &&
389 ((_pStkCrsr
=(SwPaM
*)_pStkCrsr
->GetNext()) != PCURSH
->GetStkCrsr()) );
391 FOREACHPAM_START( PCURSH
->_GetCrsr() )
392 lcl_PaMCorrRel1( PCURCRSR
, pOldNode
, aNewPos
, nCntIdx
);
395 if( PCURSH
->IsTableMode() )
396 lcl_PaMCorrRel1( PCURSH
->GetTblCrs(), pOldNode
, aNewPos
, nCntIdx
);
398 FOREACHSHELL_END( pShell
)
401 SwUnoCrsrTbl
& rTbl
= (SwUnoCrsrTbl
&)pDoc
->GetUnoCrsrTbl();
402 for( USHORT n
= 0; n
< rTbl
.Count(); ++n
)
404 FOREACHPAM_START( rTbl
[ n
] )
405 lcl_PaMCorrRel1( PCURCRSR
, pOldNode
, aNewPos
, nCntIdx
);
408 SwUnoTableCrsr
* pUnoTblCrsr
=
409 dynamic_cast<SwUnoTableCrsr
*>(rTbl
[ n
]);
412 FOREACHPAM_START( &pUnoTblCrsr
->GetSelRing() )
413 lcl_PaMCorrRel1( PCURCRSR
, pOldNode
, aNewPos
, nCntIdx
);
420 void SwDoc::CorrRel(const SwNodeIndex
& rOldNode
,
421 const SwPosition
& rNewPos
,
422 const xub_StrLen nOffset
,
425 getIDocumentMarkAccess()->correctMarksRelative(rOldNode
, rNewPos
, nOffset
);
427 { // dann die Redlines korrigieren
428 SwRedlineTbl
& rTbl
= *pRedlineTbl
;
429 SwPosition
aNewPos(rNewPos
);
430 for( USHORT n
= 0; n
< rTbl
.Count(); ++n
)
432 // liegt auf der Position ??
433 lcl_PaMCorrRel1( rTbl
[ n
], &rOldNode
.GetNode(), aNewPos
, aNewPos
.nContent
.GetIndex() + nOffset
);
438 ::PaMCorrRel(rOldNode
, rNewPos
, nOffset
);
442 SwEditShell
* SwDoc::GetEditShell( ViewShell
** ppSh
) const
444 // Layout und OLE-Shells sollten vorhanden sein!
445 if( pLayout
&& pLayout
->GetCurrShell() )
447 ViewShell
*pSh
= pLayout
->GetCurrShell(), *pVSh
= pSh
;
451 // wir suchen uns eine EditShell, falls diese existiert
453 if( pSh
->IsA( TYPE( SwEditShell
) ) )
454 return (SwEditShell
*)pSh
;
456 } while( pVSh
!= ( pSh
= (ViewShell
*)pSh
->GetNext() ));