Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <doc.hxx>
30 : : #include <node.hxx>
31 : : #include <rootfrm.hxx>
32 : : #include <editsh.hxx>
33 : : #include <viscrs.hxx>
34 : : #include <IMark.hxx>
35 : : #include <bookmrk.hxx>
36 : : #include <redline.hxx>
37 : : #include <mvsave.hxx>
38 : : #include <docary.hxx>
39 : : #include <unocrsr.hxx>
40 : : #include <swundo.hxx>
41 : : #include <hints.hxx>
42 : :
43 : : /*
44 : : * Macros to iterate over all CrsrShells
45 : : */
46 : : #define PCURSH ((SwCrsrShell*)_pStartShell)
47 : : #define FOREACHSHELL_START( pEShell ) \
48 : : {\
49 : : ViewShell *_pStartShell = pEShell; \
50 : : do { \
51 : : if( _pStartShell->IsA( TYPE( SwCrsrShell )) ) \
52 : : {
53 : :
54 : : #define FOREACHSHELL_END( pEShell ) \
55 : : } \
56 : : } while((_pStartShell=(ViewShell*)_pStartShell->GetNext())!= pEShell ); \
57 : : }
58 : :
59 : : #define PCURCRSR (_pCurrCrsr)
60 : : #define FOREACHPAM_START(pSttCrsr) \
61 : : {\
62 : : SwPaM *_pStartCrsr = pSttCrsr, *_pCurrCrsr = pSttCrsr; \
63 : : do {
64 : :
65 : : #define FOREACHPAM_END() \
66 : : } while( (_pCurrCrsr=(SwPaM *)_pCurrCrsr->GetNext()) != _pStartCrsr ); \
67 : : }
68 : :
69 : : namespace
70 : : {
71 : : // find the relevant section in which the SwUnoCrsr may wander.
72 : : // returns NULL if no restrictions apply
73 : 19134 : static const SwStartNode* lcl_FindUnoCrsrSection( const SwNode& rNode )
74 : : {
75 : 19134 : const SwStartNode* pStartNode = rNode.StartOfSectionNode();
76 [ + - + + : 94940 : while( ( pStartNode != NULL ) &&
+ + ][ + + ]
77 : 37154 : ( pStartNode->StartOfSectionNode() != pStartNode ) &&
78 : 20632 : ( pStartNode->GetStartNodeType() == SwNormalStartNode ) )
79 : 18020 : pStartNode = pStartNode->StartOfSectionNode();
80 : :
81 : 19134 : return pStartNode;
82 : : }
83 : :
84 : 33370 : static inline bool lcl_PosCorrAbs(SwPosition & rPos,
85 : : const SwPosition& rStart,
86 : : const SwPosition& rEnd,
87 : : const SwPosition& rNewPos)
88 : : {
89 [ + + ][ + + ]: 33370 : if ((rStart <= rPos) && (rPos <= rEnd))
[ + + ]
90 : : {
91 : 10713 : rPos = rNewPos;
92 : 10713 : return true;
93 : : }
94 : 33370 : return false;
95 : : };
96 : :
97 : 16685 : static inline bool lcl_PaMCorrAbs(SwPaM & rPam,
98 : : const SwPosition& rStart,
99 : : const SwPosition& rEnd,
100 : : const SwPosition& rNewPos)
101 : : {
102 : 16685 : bool bRet = false;
103 : 16685 : bRet |= lcl_PosCorrAbs(rPam.GetBound(true ), rStart, rEnd, rNewPos);
104 : 16685 : bRet |= lcl_PosCorrAbs(rPam.GetBound(false), rStart, rEnd, rNewPos);
105 : 16685 : return bRet;
106 : : };
107 : :
108 : 1309 : static inline void lcl_PaMCorrRel1(SwPaM * pPam,
109 : : SwNode const * const pOldNode,
110 : : const SwPosition& rNewPos,
111 : : const xub_StrLen nCntIdx)
112 : : {
113 [ + + ]: 3927 : for(int nb = 0; nb < 2; ++nb)
114 [ + + ]: 2618 : if(&((pPam)->GetBound(sal_Bool(nb)).nNode.GetNode()) == pOldNode)
115 : : {
116 : 1181 : (pPam)->GetBound(sal_Bool(nb)).nNode = rNewPos.nNode;
117 : 1181 : (pPam)->GetBound(sal_Bool(nb)).nContent.Assign(
118 : 1181 : const_cast<SwIndexReg*>(rNewPos.nContent.GetIdxReg()),
119 : 2362 : nCntIdx + (pPam)->GetBound(sal_Bool(nb)).nContent.GetIndex());
120 : : }
121 : 1309 : }
122 : : }
123 : :
124 : :
125 : 5250 : void PaMCorrAbs( const SwPaM& rRange,
126 : : const SwPosition& rNewPos )
127 : : {
128 [ + - ][ + - ]: 5250 : SwPosition const aStart( *rRange.Start() );
129 [ + - ][ + - ]: 5250 : SwPosition const aEnd( *rRange.End() );
130 [ + - ]: 5250 : SwPosition const aNewPos( rNewPos );
131 : 5250 : SwDoc *const pDoc = aStart.nNode.GetNode().GetDoc();
132 [ + - ]: 5250 : SwCrsrShell *const pShell = pDoc->GetEditShell();
133 : :
134 [ + + ]: 5250 : if( pShell )
135 : : {
136 [ + - ][ + - ]: 3820 : FOREACHSHELL_START( pShell )
[ + - ][ - + ]
137 : 1910 : SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
138 [ + + ]: 1910 : if( _pStkCrsr )
139 [ + - ][ - + ]: 4 : do {
[ - + ]
140 [ + - ]: 2 : lcl_PaMCorrAbs( *_pStkCrsr, aStart, aEnd, aNewPos );
141 : : } while ( (_pStkCrsr != 0 ) &&
142 : 2 : ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );
143 : :
144 [ + - ][ + - ]: 3820 : FOREACHPAM_START( PCURSH->_GetCrsr() )
[ - + ]
145 [ + - ]: 1910 : lcl_PaMCorrAbs( *PCURCRSR, aStart, aEnd, aNewPos );
146 : 1910 : FOREACHPAM_END()
147 : :
148 [ - + ]: 1910 : if( PCURSH->IsTableMode() )
149 [ # # ]: 0 : lcl_PaMCorrAbs( *PCURSH->GetTblCrs(), aStart, aEnd, aNewPos );
150 : :
151 : 1910 : FOREACHSHELL_END( pShell )
152 : : }
153 : : {
154 : 5250 : SwUnoCrsrTbl& rTbl = const_cast<SwUnoCrsrTbl&>(pDoc->GetUnoCrsrTbl());
155 : :
156 [ + + ]: 15663 : for( SwUnoCrsrTbl::iterator it = rTbl.begin(); it != rTbl.end(); ++it )
157 : : {
158 : 10413 : SwUnoCrsr *const pUnoCursor = *it;
159 : :
160 : 10413 : bool bChange = false; // has the UNO cursor been corrected?
161 : :
162 : : // determine whether the UNO cursor will leave it's designated
163 : : // section
164 : : bool const bLeaveSection =
165 : 10413 : pUnoCursor->IsRemainInSection() &&
166 : 9567 : ( lcl_FindUnoCrsrSection( aNewPos.nNode.GetNode() ) !=
167 : : lcl_FindUnoCrsrSection(
168 [ + + + + ]: 19980 : pUnoCursor->GetPoint()->nNode.GetNode() ) );
169 : :
170 [ + - ][ + - ]: 22762 : FOREACHPAM_START( pUnoCursor )
[ + + ]
171 [ + - ]: 12349 : bChange |= lcl_PaMCorrAbs( *PCURCRSR, aStart, aEnd, aNewPos );
172 : 12349 : FOREACHPAM_END()
173 : :
174 : : SwUnoTableCrsr *const pUnoTblCrsr =
175 [ - + ]: 10413 : dynamic_cast<SwUnoTableCrsr *>(*it);
176 [ + + ]: 10413 : if( pUnoTblCrsr )
177 : : {
178 [ + + ]: 2550 : FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
179 : : bChange |=
180 [ + - ]: 2424 : lcl_PaMCorrAbs( *PCURCRSR, aStart, aEnd, aNewPos );
181 : 2424 : FOREACHPAM_END()
182 : : }
183 : :
184 : : // if a UNO cursor leaves its designated section, we must inform
185 : : // (and invalidate) said cursor
186 [ + + ][ + + ]: 10413 : if (bChange && bLeaveSection)
187 : : {
188 : : // the UNO cursor has left its section. We need to notify it!
189 [ + - ]: 345 : SwMsgPoolItem aHint( RES_UNOCURSOR_LEAVES_SECTION );
190 [ + - ][ + - ]: 345 : pUnoCursor->ModifyNotification( &aHint, NULL );
191 : : }
192 : : }
193 [ + - ][ + - ]: 5250 : }
[ + - ]
194 : 5250 : }
195 : :
196 : 399 : void SwDoc::CorrAbs(const SwNodeIndex& rOldNode,
197 : : const SwPosition& rNewPos,
198 : : const xub_StrLen nOffset,
199 : : sal_Bool bMoveCrsr)
200 : : {
201 : 399 : SwCntntNode *const pCntntNode( rOldNode.GetNode().GetCntntNode() );
202 : : SwPaM const aPam(rOldNode, 0,
203 [ + - ][ + - ]: 399 : rOldNode, (pCntntNode) ? pCntntNode->Len() : 0);
[ + - ]
204 [ + - ]: 399 : SwPosition aNewPos(rNewPos);
205 [ + - ]: 399 : aNewPos.nContent += nOffset;
206 : :
207 [ + - ][ + - ]: 399 : getIDocumentMarkAccess()->correctMarksAbsolute(rOldNode, rNewPos, nOffset);
208 : : { // fix redlines
209 : 399 : SwRedlineTbl& rTbl = *pRedlineTbl;
210 [ - + ]: 399 : for (sal_uInt16 n = 0; n < rTbl.size(); )
211 : : {
212 : : // is on position ??
213 [ # # ]: 0 : SwRedline *const pRedline( rTbl[ n ] );
214 : : bool const bChanged =
215 [ # # ][ # # ]: 0 : lcl_PaMCorrAbs(*pRedline, *aPam.Start(), *aPam.End(), aNewPos);
[ # # ]
216 : : // clean up empty redlines: docredln.cxx asserts these as invalid
217 [ # # ][ # # ]: 0 : if (bChanged && (*pRedline->GetPoint() == *pRedline->GetMark())
[ # # # # ]
[ # # ]
218 : 0 : && (pRedline->GetContentIdx() == NULL))
219 : : {
220 [ # # ]: 0 : rTbl.DeleteAndDestroy(n);
221 : : }
222 : : else
223 : : {
224 : 0 : ++n;
225 : : }
226 : : }
227 : : }
228 : :
229 [ + - ]: 399 : if(bMoveCrsr)
230 : : {
231 [ + - ]: 399 : ::PaMCorrAbs(aPam, aNewPos);
232 [ + - ][ + - ]: 399 : }
233 : 399 : }
234 : :
235 : 6 : void SwDoc::CorrAbs(const SwPaM& rRange,
236 : : const SwPosition& rNewPos,
237 : : sal_Bool bMoveCrsr)
238 : : {
239 [ + - ][ + - ]: 6 : SwPosition aStart(*rRange.Start());
240 [ + - ][ + - ]: 6 : SwPosition aEnd(*rRange.End());
241 [ + - ]: 6 : SwPosition aNewPos(rNewPos);
242 : :
243 : : _DelBookmarks(aStart.nNode, aEnd.nNode, NULL,
244 [ + - ]: 6 : &aStart.nContent, &aEnd.nContent);
245 [ + - ]: 6 : if(bMoveCrsr)
246 [ + - ][ + - ]: 6 : ::PaMCorrAbs(rRange, rNewPos);
[ + - ][ + - ]
247 : 6 : }
248 : :
249 : 150 : void SwDoc::CorrAbs(const SwNodeIndex& rStartNode,
250 : : const SwNodeIndex& rEndNode,
251 : : const SwPosition& rNewPos,
252 : : sal_Bool bMoveCrsr)
253 : : {
254 : 150 : _DelBookmarks(rStartNode, rEndNode);
255 : :
256 [ + - ]: 150 : if(bMoveCrsr)
257 : : {
258 : 150 : SwCntntNode *const pCntntNode( rEndNode.GetNode().GetCntntNode() );
259 : : SwPaM const aPam(rStartNode, 0,
260 [ + - ][ + - ]: 150 : rEndNode, (pCntntNode) ? pCntntNode->Len() : 0);
[ + + ]
261 [ + - ][ + - ]: 150 : ::PaMCorrAbs(aPam, rNewPos);
262 : : }
263 : 150 : }
264 : :
265 : :
266 : :
267 : :
268 : :
269 : 638 : void PaMCorrRel( const SwNodeIndex &rOldNode,
270 : : const SwPosition &rNewPos,
271 : : const xub_StrLen nOffset )
272 : : {
273 : 638 : const SwNode* pOldNode = &rOldNode.GetNode();
274 [ + - ]: 638 : SwPosition aNewPos( rNewPos );
275 : 638 : const SwDoc* pDoc = pOldNode->GetDoc();
276 : :
277 : 638 : xub_StrLen nCntIdx = rNewPos.nContent.GetIndex() + nOffset;
278 : :
279 [ + - ]: 638 : SwCrsrShell* pShell = pDoc->GetEditShell();
280 [ + + ]: 638 : if( pShell )
281 : : {
282 [ + - ][ + - ]: 52 : FOREACHSHELL_START( pShell )
[ + - ][ - + ]
283 : 26 : SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
284 [ - + ]: 26 : if( _pStkCrsr )
285 [ # # ][ # # ]: 0 : do {
[ # # ]
286 [ # # ]: 0 : lcl_PaMCorrRel1( _pStkCrsr, pOldNode, aNewPos, nCntIdx );
287 : : } while ( (_pStkCrsr != 0 ) &&
288 : 0 : ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );
289 : :
290 [ + - ][ + - ]: 52 : FOREACHPAM_START( PCURSH->_GetCrsr() )
[ - + ]
291 [ + - ]: 26 : lcl_PaMCorrRel1( PCURCRSR, pOldNode, aNewPos, nCntIdx);
292 : 26 : FOREACHPAM_END()
293 : :
294 [ - + ]: 26 : if( PCURSH->IsTableMode() )
295 [ # # ]: 0 : lcl_PaMCorrRel1( PCURSH->GetTblCrs(), pOldNode, aNewPos, nCntIdx );
296 : :
297 : 26 : FOREACHSHELL_END( pShell )
298 : : }
299 : : {
300 : 638 : SwUnoCrsrTbl& rTbl = (SwUnoCrsrTbl&)pDoc->GetUnoCrsrTbl();
301 [ + + ]: 1921 : for( SwUnoCrsrTbl::iterator it = rTbl.begin(); it != rTbl.end(); ++it )
302 : : {
303 [ + - ][ + - ]: 2566 : FOREACHPAM_START( *it )
[ - + ]
304 [ + - ]: 1283 : lcl_PaMCorrRel1( PCURCRSR, pOldNode, aNewPos, nCntIdx );
305 : 1283 : FOREACHPAM_END()
306 : :
307 : : SwUnoTableCrsr* pUnoTblCrsr =
308 [ - + ]: 1283 : dynamic_cast<SwUnoTableCrsr*>(*it);
309 [ - + ]: 1283 : if( pUnoTblCrsr )
310 : : {
311 [ # # ]: 0 : FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
312 [ # # ]: 0 : lcl_PaMCorrRel1( PCURCRSR, pOldNode, aNewPos, nCntIdx );
313 : 0 : FOREACHPAM_END()
314 : : }
315 : : }
316 [ + - ]: 638 : }
317 : 638 : }
318 : :
319 : 638 : void SwDoc::CorrRel(const SwNodeIndex& rOldNode,
320 : : const SwPosition& rNewPos,
321 : : const xub_StrLen nOffset,
322 : : sal_Bool bMoveCrsr)
323 : : {
324 : 638 : getIDocumentMarkAccess()->correctMarksRelative(rOldNode, rNewPos, nOffset);
325 : :
326 : : { // fix the Redlines
327 : 638 : SwRedlineTbl& rTbl = *pRedlineTbl;
328 [ + - ]: 638 : SwPosition aNewPos(rNewPos);
329 [ - + ]: 638 : for( sal_uInt16 n = 0; n < rTbl.size(); ++n )
330 : : {
331 : : // liegt auf der Position ??
332 [ # # ][ # # ]: 0 : lcl_PaMCorrRel1( rTbl[ n ], &rOldNode.GetNode(), aNewPos, aNewPos.nContent.GetIndex() + nOffset );
333 [ + - ]: 638 : }
334 : : }
335 : :
336 [ + - ]: 638 : if(bMoveCrsr)
337 : 638 : ::PaMCorrRel(rOldNode, rNewPos, nOffset);
338 : 638 : }
339 : :
340 : :
341 : 30011 : SwEditShell* SwDoc::GetEditShell( ViewShell** ppSh ) const
342 : : {
343 : : // Layout and OLE shells should be available
344 [ + + ]: 30011 : if( pCurrentView )
345 : : {
346 : 23645 : ViewShell *pSh = pCurrentView, *pVSh = pSh;
347 [ + + ]: 23645 : if( ppSh )
348 : 10679 : *ppSh = pSh;
349 : :
350 : : // look for an EditShell (if it exists)
351 [ # # ]: 0 : do {
352 [ + - ]: 23645 : if( pSh->IsA( TYPE( SwEditShell ) ) )
353 : 23645 : return (SwEditShell*)pSh;
354 : :
355 : 0 : } while( pVSh != ( pSh = (ViewShell*)pSh->GetNext() ));
356 : : }
357 [ + + ]: 6366 : else if( ppSh )
358 : 32 : *ppSh = 0; //swmod 071029//swmod 071225
359 : :
360 : 30011 : return 0;
361 : : }
362 : :
363 : 0 : ::sw::IShellCursorSupplier * SwDoc::GetIShellCursorSupplier()
364 : : {
365 [ # # ]: 0 : return GetEditShell(0);
366 : : }
367 : :
368 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|