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 <tools/gen.hxx>
21 : #include <hintids.hxx>
22 : #include <editeng/protitem.hxx>
23 : #include <cntfrm.hxx>
24 : #include <pagefrm.hxx>
25 : #include <doc.hxx>
26 : #include <docary.hxx>
27 : #include <pam.hxx>
28 : #include <pamtyp.hxx>
29 : #include <txtfrm.hxx>
30 : #include <fmtcntnt.hxx>
31 : #include <frmatr.hxx>
32 : #include <swtable.hxx>
33 : #include <crsskip.hxx>
34 :
35 : // Formular view
36 : #include <flyfrm.hxx>
37 : #include <fmteiro.hxx>
38 : #include <section.hxx>
39 : #include <sectfrm.hxx>
40 : #include <ndtxt.hxx>
41 :
42 : #include <IMark.hxx>
43 : #include <hints.hxx>
44 :
45 : #include <xmloff/odffields.hxx>
46 :
47 : // for the dump "MSC-" compiler
48 25027 : inline xub_StrLen GetSttOrEnd( bool bCondition, const SwCntntNode& rNd )
49 : {
50 25027 : return bCondition ? 0 : rNd.Len();
51 : }
52 :
53 12680 : SwPosition::SwPosition( const SwNodeIndex & rNodeIndex, const SwIndex & rCntnt )
54 12680 : : nNode( rNodeIndex ), nContent( rCntnt )
55 : {
56 12680 : }
57 :
58 205418 : SwPosition::SwPosition( const SwNodeIndex & rNodeIndex )
59 205418 : : nNode( rNodeIndex ), nContent( nNode.GetNode().GetCntntNode() )
60 : {
61 205418 : }
62 :
63 86622 : SwPosition::SwPosition( const SwNode& rNode )
64 86622 : : nNode( rNode ), nContent( nNode.GetNode().GetCntntNode() )
65 : {
66 86622 : }
67 :
68 5631 : SwPosition::SwPosition( SwCntntNode & rNode, const xub_StrLen nOffset )
69 5631 : : nNode( rNode ), nContent( &rNode, nOffset )
70 : {
71 5631 : }
72 :
73 :
74 649316 : SwPosition::SwPosition( const SwPosition & rPos )
75 649316 : : nNode( rPos.nNode ), nContent( rPos.nContent )
76 : {
77 649316 : }
78 :
79 135864 : SwPosition &SwPosition::operator=(const SwPosition &rPos)
80 : {
81 135864 : nNode = rPos.nNode;
82 135864 : nContent = rPos.nContent;
83 135864 : return *this;
84 : }
85 :
86 :
87 487977 : bool SwPosition::operator<(const SwPosition &rPos) const
88 : {
89 487977 : if( nNode < rPos.nNode )
90 44131 : return true;
91 443846 : if( nNode == rPos.nNode )
92 : {
93 : // note that positions with text node but no SwIndex registered are
94 : // created for text frames anchored at para (see SwXFrame::getAnchor())
95 420089 : SwIndexReg const*const pThisReg(nContent.GetIdxReg());
96 420089 : SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
97 420089 : if (pThisReg && pOtherReg)
98 : {
99 419995 : return (nContent < rPos.nContent);
100 : }
101 : else // by convention position with no index is smaller
102 : {
103 94 : return (pOtherReg) ? true : false;
104 : }
105 : }
106 23757 : return false;
107 : }
108 :
109 :
110 121873 : bool SwPosition::operator>(const SwPosition &rPos) const
111 : {
112 121873 : if(nNode > rPos.nNode )
113 24789 : return true;
114 97084 : if( nNode == rPos.nNode )
115 : {
116 : // note that positions with text node but no SwIndex registered are
117 : // created for text frames anchored at para (see SwXFrame::getAnchor())
118 94411 : SwIndexReg const*const pThisReg(nContent.GetIdxReg());
119 94411 : SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
120 94411 : if (pThisReg && pOtherReg)
121 : {
122 91657 : return (nContent > rPos.nContent);
123 : }
124 : else // by convention position with no index is smaller
125 : {
126 2754 : return (pThisReg) ? true : false;
127 : }
128 : }
129 2673 : return false;
130 : }
131 :
132 :
133 1268433 : bool SwPosition::operator<=(const SwPosition &rPos) const
134 : {
135 1268433 : if(nNode < rPos.nNode )
136 281869 : return true;
137 986564 : if( nNode == rPos.nNode )
138 : {
139 : // note that positions with text node but no SwIndex registered are
140 : // created for text frames anchored at para (see SwXFrame::getAnchor())
141 309816 : SwIndexReg const*const pThisReg(nContent.GetIdxReg());
142 309816 : SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
143 309816 : if (pThisReg && pOtherReg)
144 : {
145 307464 : return (nContent <= rPos.nContent);
146 : }
147 : else // by convention position with no index is smaller
148 : {
149 2352 : return (pThisReg) ? false : true;
150 : }
151 : }
152 676748 : return false;
153 : }
154 :
155 :
156 2487914 : bool SwPosition::operator>=(const SwPosition &rPos) const
157 : {
158 2487914 : if(nNode > rPos.nNode )
159 43 : return true;
160 2487871 : if( nNode == rPos.nNode )
161 : {
162 : // note that positions with text node but no SwIndex registered are
163 : // created for text frames anchored at para (see SwXFrame::getAnchor())
164 2459104 : SwIndexReg const*const pThisReg(nContent.GetIdxReg());
165 2459104 : SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
166 2459104 : if (pThisReg && pOtherReg)
167 : {
168 2457476 : return (nContent >= rPos.nContent);
169 : }
170 : else // by convention position with no index is smaller
171 : {
172 1628 : return (pOtherReg) ? false : true;
173 : }
174 : }
175 28767 : return false;
176 : }
177 :
178 :
179 6123 : bool SwPosition::operator==(const SwPosition &rPos) const
180 : {
181 6123 : return (nNode == rPos.nNode)
182 : // GetIndexReg may be null for FLY_AT_PARA frame anchor position
183 5557 : && (nContent.GetIdxReg() == rPos.nContent.GetIdxReg())
184 11664 : && (nContent == rPos.nContent);
185 : }
186 :
187 :
188 93070 : bool SwPosition::operator!=(const SwPosition &rPos) const
189 : {
190 93070 : return (nNode != rPos.nNode)
191 : // GetIndexReg may be null for FLY_AT_PARA frame anchor position
192 92474 : || (nContent.GetIdxReg() != rPos.nContent.GetIdxReg())
193 185544 : || (nContent != rPos.nContent);
194 : }
195 :
196 1376 : SwDoc * SwPosition::GetDoc() const
197 : {
198 1376 : return nNode.GetNode().GetDoc();
199 : }
200 :
201 :
202 : enum CHKSECTION { Chk_Both, Chk_One, Chk_None };
203 :
204 :
205 8423 : static CHKSECTION lcl_TstIdx( sal_uLong nSttIdx, sal_uLong nEndIdx, const SwNode& rEndNd )
206 : {
207 8423 : sal_uLong nStt = rEndNd.StartOfSectionIndex(), nEnd = rEndNd.GetIndex();
208 8423 : CHKSECTION eSec = nStt < nSttIdx && nEnd >= nSttIdx ? Chk_One : Chk_None;
209 8423 : if( nStt < nEndIdx && nEnd >= nEndIdx )
210 7888 : return( eSec == Chk_One ? Chk_Both : Chk_One );
211 535 : return eSec;
212 : }
213 :
214 :
215 419 : static bool lcl_ChkOneRange( CHKSECTION eSec, bool bChkSections,
216 : const SwNode& rBaseEnd, sal_uLong nStt, sal_uLong nEnd )
217 : {
218 419 : if( eSec != Chk_Both )
219 1 : return false;
220 :
221 418 : if( !bChkSections )
222 0 : return true;
223 :
224 : // search the surrounding section
225 418 : const SwNodes& rNds = rBaseEnd.GetNodes();
226 418 : const SwNode *pTmp, *pNd = rNds[ nStt ];
227 418 : if( !pNd->IsStartNode() )
228 415 : pNd = pNd->StartOfSectionNode();
229 :
230 418 : if( pNd == rNds[ nEnd ]->StartOfSectionNode() )
231 306 : return true; // same StartNode, same section
232 :
233 : // already on a base node => error
234 112 : if( !pNd->StartOfSectionIndex() )
235 0 : return false;
236 :
237 246 : while( ( pTmp = pNd->StartOfSectionNode())->EndOfSectionNode() !=
238 : &rBaseEnd )
239 22 : pNd = pTmp;
240 :
241 112 : sal_uLong nSttIdx = pNd->GetIndex(), nEndIdx = pNd->EndOfSectionIndex();
242 112 : return nSttIdx <= nStt && nStt <= nEndIdx &&
243 212 : nSttIdx <= nEnd && nEnd <= nEndIdx;
244 : }
245 :
246 :
247 7892 : bool CheckNodesRange( const SwNodeIndex& rStt,
248 : const SwNodeIndex& rEnd, bool bChkSection )
249 : {
250 7892 : const SwNodes& rNds = rStt.GetNodes();
251 7892 : sal_uLong nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex();
252 7892 : CHKSECTION eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfContent() );
253 7892 : if( Chk_None != eSec )
254 7473 : return eSec == Chk_Both;
255 :
256 419 : eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfAutotext() );
257 419 : if( Chk_None != eSec )
258 : return lcl_ChkOneRange( eSec, bChkSection,
259 363 : rNds.GetEndOfAutotext(), nStt, nEnd );
260 :
261 56 : eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfPostIts() );
262 56 : if( Chk_None != eSec )
263 : return lcl_ChkOneRange( eSec, bChkSection,
264 0 : rNds.GetEndOfPostIts(), nStt, nEnd );
265 :
266 56 : eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfInserts() );
267 56 : if( Chk_None != eSec )
268 : return lcl_ChkOneRange( eSec, bChkSection,
269 56 : rNds.GetEndOfInserts(), nStt, nEnd );
270 :
271 0 : eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfRedlines() );
272 0 : if( Chk_None != eSec )
273 : return lcl_ChkOneRange( eSec, bChkSection,
274 0 : rNds.GetEndOfRedlines(), nStt, nEnd );
275 :
276 0 : return false; // somewhere in between => error
277 : }
278 :
279 :
280 48635 : sal_Bool GoNext(SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode )
281 : {
282 48635 : if( pNd->IsCntntNode() )
283 48610 : return ((SwCntntNode*)pNd)->GoNext( pIdx, nMode );
284 25 : return sal_False;
285 : }
286 :
287 :
288 35452 : sal_Bool GoPrevious( SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode )
289 : {
290 35452 : if( pNd->IsCntntNode() )
291 35441 : return ((SwCntntNode*)pNd)->GoPrevious( pIdx, nMode );
292 11 : return sal_False;
293 : }
294 :
295 :
296 10984 : SwCntntNode* GoNextNds( SwNodeIndex* pIdx, sal_Bool bChk )
297 : {
298 10984 : SwNodeIndex aIdx( *pIdx );
299 10984 : SwCntntNode* pNd = aIdx.GetNodes().GoNext( &aIdx );
300 10984 : if( pNd )
301 : {
302 10202 : if( bChk && 1 != aIdx.GetIndex() - pIdx->GetIndex() &&
303 1261 : !CheckNodesRange( *pIdx, aIdx, true ) )
304 527 : pNd = 0;
305 : else
306 8414 : *pIdx = aIdx;
307 : }
308 10984 : return pNd;
309 : }
310 :
311 :
312 18416 : SwCntntNode* GoPreviousNds( SwNodeIndex * pIdx, sal_Bool bChk )
313 : {
314 18416 : SwNodeIndex aIdx( *pIdx );
315 18416 : SwCntntNode* pNd = aIdx.GetNodes().GoPrevious( &aIdx );
316 18416 : if( pNd )
317 : {
318 18457 : if( bChk && 1 != pIdx->GetIndex() - aIdx.GetIndex() &&
319 81 : !CheckNodesRange( *pIdx, aIdx, true ) )
320 16 : pNd = 0;
321 : else
322 18360 : *pIdx = aIdx;
323 : }
324 18416 : return pNd;
325 : }
326 :
327 :
328 108057 : SwPaM::SwPaM( const SwPosition& rPos, SwPaM* pRing )
329 : : Ring( pRing )
330 : , m_Bound1( rPos )
331 108057 : , m_Bound2( rPos.nNode.GetNode().GetNodes() ) // default initialize
332 : , m_pPoint( &m_Bound1 )
333 : , m_pMark( m_pPoint )
334 216114 : , m_bIsInFrontOfLabel( false )
335 : {
336 108057 : }
337 :
338 23178 : SwPaM::SwPaM( const SwPosition& rMark, const SwPosition& rPoint, SwPaM* pRing )
339 : : Ring( pRing )
340 : , m_Bound1( rMark )
341 : , m_Bound2( rPoint )
342 : , m_pPoint( &m_Bound2 )
343 : , m_pMark( &m_Bound1 )
344 23178 : , m_bIsInFrontOfLabel( false )
345 : {
346 23178 : }
347 :
348 145 : SwPaM::SwPaM( const SwNodeIndex& rMark, const SwNodeIndex& rPoint,
349 : long nMarkOffset, long nPointOffset, SwPaM* pRing )
350 : : Ring( pRing )
351 : , m_Bound1( rMark )
352 : , m_Bound2( rPoint )
353 : , m_pPoint( &m_Bound2 )
354 : , m_pMark( &m_Bound1 )
355 145 : , m_bIsInFrontOfLabel( false )
356 : {
357 145 : if ( nMarkOffset )
358 : {
359 0 : m_pMark->nNode += nMarkOffset;
360 : }
361 145 : if ( nPointOffset )
362 : {
363 0 : m_pPoint->nNode += nPointOffset;
364 : }
365 :
366 145 : m_Bound1.nContent.Assign( m_Bound1.nNode.GetNode().GetCntntNode(), 0 );
367 145 : m_Bound2.nContent.Assign( m_Bound2.nNode.GetNode().GetCntntNode(), 0 );
368 145 : }
369 :
370 7048 : SwPaM::SwPaM( const SwNode& rMark, const SwNode& rPoint,
371 : long nMarkOffset, long nPointOffset, SwPaM* pRing )
372 : : Ring( pRing )
373 : , m_Bound1( rMark )
374 : , m_Bound2( rPoint )
375 : , m_pPoint( &m_Bound2 )
376 : , m_pMark( &m_Bound1 )
377 7048 : , m_bIsInFrontOfLabel( false )
378 : {
379 7048 : if ( nMarkOffset )
380 : {
381 0 : m_pMark->nNode += nMarkOffset;
382 : }
383 7048 : if ( nPointOffset )
384 : {
385 0 : m_pPoint->nNode += nPointOffset;
386 : }
387 :
388 7048 : m_Bound1.nContent.Assign( m_Bound1.nNode.GetNode().GetCntntNode(), 0 );
389 7048 : m_Bound2.nContent.Assign( m_Bound2.nNode.GetNode().GetCntntNode(), 0 );
390 7048 : }
391 :
392 1625 : SwPaM::SwPaM( const SwNodeIndex& rMark , xub_StrLen nMarkCntnt,
393 : const SwNodeIndex& rPoint, xub_StrLen nPointCntnt, SwPaM* pRing )
394 : : Ring( pRing )
395 : , m_Bound1( rMark )
396 : , m_Bound2( rPoint )
397 : , m_pPoint( &m_Bound2 )
398 : , m_pMark( &m_Bound1 )
399 1625 : , m_bIsInFrontOfLabel( false )
400 : {
401 1625 : m_pPoint->nContent.Assign( rPoint.GetNode().GetCntntNode(), nPointCntnt);
402 1625 : m_pMark ->nContent.Assign( rMark .GetNode().GetCntntNode(), nMarkCntnt );
403 1625 : }
404 :
405 36 : SwPaM::SwPaM( const SwNode& rMark , xub_StrLen nMarkCntnt,
406 : const SwNode& rPoint, xub_StrLen nPointCntnt, SwPaM* pRing )
407 : : Ring( pRing )
408 : , m_Bound1( rMark )
409 : , m_Bound2( rPoint )
410 : , m_pPoint( &m_Bound2 )
411 : , m_pMark( &m_Bound1 )
412 36 : , m_bIsInFrontOfLabel( false )
413 : {
414 36 : m_pPoint->nContent.Assign( m_pPoint->nNode.GetNode().GetCntntNode(),
415 72 : nPointCntnt);
416 36 : m_pMark ->nContent.Assign( m_pMark ->nNode.GetNode().GetCntntNode(),
417 72 : nMarkCntnt );
418 36 : }
419 :
420 9522 : SwPaM::SwPaM( const SwNode& rNode, xub_StrLen nCntnt, SwPaM* pRing )
421 : : Ring( pRing )
422 : , m_Bound1( rNode )
423 9522 : , m_Bound2( m_Bound1.nNode.GetNode().GetNodes() ) // default initialize
424 : , m_pPoint( &m_Bound1 )
425 : , m_pMark( &m_Bound1 )
426 19044 : , m_bIsInFrontOfLabel( false )
427 : {
428 9522 : m_pPoint->nContent.Assign( m_pPoint->nNode.GetNode().GetCntntNode(),
429 19044 : nCntnt );
430 9522 : }
431 :
432 37641 : SwPaM::SwPaM( const SwNodeIndex& rNodeIdx, xub_StrLen nCntnt, SwPaM* pRing )
433 : : Ring( pRing )
434 : , m_Bound1( rNodeIdx )
435 37641 : , m_Bound2( rNodeIdx.GetNode().GetNodes() ) // default initialize
436 : , m_pPoint( &m_Bound1 )
437 : , m_pMark( &m_Bound1 )
438 75282 : , m_bIsInFrontOfLabel( false )
439 : {
440 37641 : m_pPoint->nContent.Assign( rNodeIdx.GetNode().GetCntntNode(), nCntnt );
441 37641 : }
442 :
443 202632 : SwPaM::~SwPaM() {}
444 :
445 : // @@@ semantic: no copy ctor.
446 134 : SwPaM::SwPaM( SwPaM &rPam )
447 : : Ring( &rPam )
448 : , m_Bound1( *(rPam.m_pPoint) )
449 : , m_Bound2( *(rPam.m_pMark) )
450 134 : , m_pPoint( &m_Bound1 ), m_pMark( rPam.HasMark() ? &m_Bound2 : m_pPoint )
451 268 : , m_bIsInFrontOfLabel( false )
452 : {
453 134 : }
454 :
455 : // @@@ semantic: no copy assignment for super class Ring.
456 11 : SwPaM &SwPaM::operator=( const SwPaM &rPam )
457 : {
458 11 : *m_pPoint = *( rPam.m_pPoint );
459 11 : if ( rPam.HasMark() )
460 : {
461 2 : SetMark();
462 2 : *m_pMark = *( rPam.m_pMark );
463 : }
464 : else
465 : {
466 9 : DeleteMark();
467 : }
468 11 : return *this;
469 : }
470 :
471 72684 : void SwPaM::SetMark()
472 : {
473 72684 : if (m_pPoint == &m_Bound1)
474 : {
475 72640 : m_pMark = &m_Bound2;
476 : }
477 : else
478 : {
479 44 : m_pMark = &m_Bound1;
480 : }
481 72684 : (*m_pMark) = (*m_pPoint);
482 72684 : }
483 :
484 : #ifdef DBG_UTIL
485 :
486 : void SwPaM::Exchange()
487 : {
488 : if (m_pPoint != m_pMark)
489 : {
490 : SwPosition *pTmp = m_pPoint;
491 : m_pPoint = m_pMark;
492 : m_pMark = pTmp;
493 : }
494 : }
495 : #endif
496 :
497 : /// movement of cursor
498 117490 : bool SwPaM::Move( SwMoveFn fnMove, SwGoInDoc fnGo )
499 : {
500 117490 : const bool bRet = (*fnGo)( *this, fnMove );
501 :
502 117490 : m_bIsInFrontOfLabel = false;
503 :
504 117490 : return bRet;
505 : }
506 :
507 : /** make a new region
508 :
509 : Sets the first SwPaM onto the given SwPaM, or to the beginning or end of a
510 : document. SPoint stays at its position, GetMark will be changed respectively.
511 :
512 : @param fnMove Contains information if beginning or end of document.
513 : @param pOrigRg The given region.
514 :
515 : @return Newly created area.
516 : */
517 90 : SwPaM* SwPaM::MakeRegion( SwMoveFn fnMove, const SwPaM * pOrigRg )
518 : {
519 : SwPaM* pPam;
520 90 : if( pOrigRg == 0 )
521 : {
522 0 : pPam = new SwPaM( *m_pPoint );
523 0 : pPam->SetMark(); // set beginning
524 0 : pPam->Move( fnMove, fnGoSection); // to beginning or end of a node
525 :
526 : // set SPoint onto its old position; set GetMark to the "end"
527 0 : pPam->Exchange();
528 : }
529 : else
530 : {
531 90 : pPam = new SwPaM( *(SwPaM*)pOrigRg ); // given search area
532 : // make sure that SPoint is on the "real" start position
533 : // FORWARD: SPoint always smaller than GetMark
534 : // BACKWARD: SPoint always bigger than GetMark
535 90 : if( (pPam->GetMark()->*fnMove->fnCmpOp)( *pPam->GetPoint() ) )
536 90 : pPam->Exchange();
537 : }
538 90 : return pPam;
539 : }
540 :
541 3624 : SwPaM & SwPaM::Normalize(bool bPointFirst)
542 : {
543 3624 : if (HasMark())
544 7060 : if ( ( bPointFirst && *m_pPoint > *m_pMark) ||
545 6634 : (!bPointFirst && *m_pPoint < *m_pMark) )
546 : {
547 389 : Exchange();
548 : }
549 :
550 3624 : return *this;
551 : }
552 :
553 : /// return page number at cursor (for reader and page bound frames)
554 13 : sal_uInt16 SwPaM::GetPageNum( bool bAtPoint, const Point* pLayPos )
555 : {
556 : const SwCntntFrm* pCFrm;
557 : const SwPageFrm *pPg;
558 : const SwCntntNode *pNd ;
559 13 : const SwPosition* pPos = bAtPoint ? m_pPoint : m_pMark;
560 :
561 39 : if( 0 != ( pNd = pPos->nNode.GetNode().GetCntntNode() ) &&
562 26 : 0 != ( pCFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), pLayPos, pPos, sal_False )) &&
563 13 : 0 != ( pPg = pCFrm->FindPageFrm() ))
564 13 : return pPg->GetPhyPageNum();
565 0 : return 0;
566 : }
567 :
568 : // Formular view - See also SwCrsrShell::IsCrsrReadonly()
569 0 : static const SwFrm* lcl_FindEditInReadonlyFrm( const SwFrm& rFrm )
570 : {
571 0 : const SwFrm* pRet = 0;
572 :
573 : const SwFlyFrm* pFly;
574 : const SwSectionFrm* pSectionFrm;
575 :
576 0 : if( rFrm.IsInFly() &&
577 0 : (pFly = rFrm.FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() &&
578 0 : pFly->Lower() &&
579 0 : !pFly->Lower()->IsNoTxtFrm() )
580 : {
581 0 : pRet = pFly;
582 : }
583 0 : else if ( rFrm.IsInSct() &&
584 0 : 0 != ( pSectionFrm = rFrm.FindSctFrm() )->GetSection() &&
585 0 : pSectionFrm->GetSection()->IsEditInReadonlyFlag() )
586 : {
587 0 : pRet = pSectionFrm;
588 : }
589 :
590 0 : return pRet;
591 : }
592 :
593 : /// is in protected section or selection surrounds something protected
594 12142 : bool SwPaM::HasReadonlySel( bool bFormView, bool bAnnotationMode ) const
595 : {
596 12142 : bool bRet = false;
597 12142 : Point aTmpPt;
598 : const SwCntntNode *pNd;
599 : const SwCntntFrm *pFrm;
600 :
601 12142 : if( 0 != ( pNd = GetPoint()->nNode.GetNode().GetCntntNode() ))
602 12142 : pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), &aTmpPt, GetPoint(), sal_False );
603 : else
604 0 : pFrm = 0;
605 :
606 : // Will be set if point/mark are inside edit-in-readonly environment
607 12142 : const SwFrm* pSttEIRFrm = 0;
608 12142 : const SwFrm* pEndEIRFrm = 0;
609 :
610 12142 : if( pFrm && ( pFrm->IsProtected() ||
611 0 : ( bFormView && 0 == ( pSttEIRFrm = lcl_FindEditInReadonlyFrm( *pFrm ) ) ) ) )
612 0 : bRet = true;
613 12142 : else if( pNd )
614 : {
615 12142 : const SwSectionNode* pSNd = pNd->GetSectionNode();
616 12142 : if( pSNd && ( pSNd->GetSection().IsProtectFlag() ||
617 0 : (bFormView && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
618 0 : bRet = true;
619 : }
620 :
621 12142 : if( !bRet && HasMark() && GetPoint()->nNode != GetMark()->nNode )
622 : {
623 11 : if( 0 != ( pNd = GetMark()->nNode.GetNode().GetCntntNode() ))
624 11 : pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), &aTmpPt, GetMark(), sal_False );
625 : else
626 0 : pFrm = 0;
627 :
628 11 : if( pFrm && ( pFrm->IsProtected() ||
629 0 : ( bFormView && 0 == ( pEndEIRFrm = lcl_FindEditInReadonlyFrm( *pFrm ) ) ) ) )
630 0 : bRet = true;
631 11 : else if( pNd )
632 : {
633 11 : const SwSectionNode* pSNd = pNd->GetSectionNode();
634 11 : if( pSNd && ( pSNd->GetSection().IsProtectFlag() ||
635 0 : (bFormView && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
636 0 : bRet = true;
637 : }
638 :
639 11 : if ( !bRet && bFormView )
640 : {
641 : // Check if start and end frame are inside the _same_
642 : // edit-in-readonly-environment. Otherwise we better return 'true'
643 0 : if ( pSttEIRFrm != pEndEIRFrm )
644 0 : bRet = true;
645 : }
646 :
647 : // protected section in selection
648 11 : if( !bRet )
649 : {
650 11 : sal_uLong nSttIdx = GetMark()->nNode.GetIndex(),
651 11 : nEndIdx = GetPoint()->nNode.GetIndex();
652 11 : if( nEndIdx <= nSttIdx )
653 : {
654 0 : sal_uLong nTmp = nSttIdx;
655 0 : nSttIdx = nEndIdx;
656 0 : nEndIdx = nTmp;
657 : }
658 :
659 : // If a protected section should be between nodes, then the
660 : // selection needs to contain already x nodes.
661 : // (TxtNd, SectNd, TxtNd, EndNd, TxtNd )
662 11 : if( nSttIdx + 3 < nEndIdx )
663 : {
664 11 : const SwSectionFmts& rFmts = GetDoc()->GetSections();
665 22 : for( sal_uInt16 n = rFmts.size(); n; )
666 : {
667 0 : const SwSectionFmt* pFmt = rFmts[ --n ];
668 0 : if( pFmt->GetProtect().IsCntntProtected() )
669 : {
670 0 : const SwFmtCntnt& rCntnt = pFmt->GetCntnt(sal_False);
671 : OSL_ENSURE( rCntnt.GetCntntIdx(), "where is the SectionNode?" );
672 0 : sal_uLong nIdx = rCntnt.GetCntntIdx()->GetIndex();
673 0 : if( nSttIdx <= nIdx && nEndIdx >= nIdx &&
674 0 : rCntnt.GetCntntIdx()->GetNode().GetNodes().IsDocNodes() )
675 : {
676 0 : bRet = true;
677 0 : break;
678 : }
679 : }
680 : }
681 : }
682 : }
683 : }
684 : //FIXME FieldBk
685 : // TODO: Form Protection when Enhanced Fields are enabled
686 12142 : const SwDoc *pDoc = GetDoc();
687 12142 : sw::mark::IMark* pA = NULL;
688 12142 : sw::mark::IMark* pB = NULL;
689 12142 : bool bUnhandledMark = false;
690 12142 : bool bCommentrangeMark = false;
691 12142 : const IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess();
692 12142 : if ( pDoc )
693 : {
694 12142 : pA = GetPoint() ? pMarksAccess->getFieldmarkFor( *GetPoint( ) ) : NULL;
695 12142 : pB = GetMark( ) ? pMarksAccess->getFieldmarkFor( *GetMark( ) ) : pA;
696 :
697 12142 : sw::mark::IFieldmark* pFieldmark = pMarksAccess->getFieldmarkFor( *GetPoint() );
698 12142 : if ( pFieldmark )
699 : {
700 2 : bUnhandledMark = pFieldmark->GetFieldname( ) == ODF_UNHANDLED;
701 2 : if (!bUnhandledMark)
702 2 : bCommentrangeMark = pFieldmark->GetFieldname() == ODF_COMMENTRANGE;
703 : }
704 : // Allow editing selection right before a commented range.
705 12142 : if (!bCommentrangeMark && GetMark())
706 : {
707 12142 : pFieldmark = pMarksAccess->getFieldmarkFor(*GetMark());
708 12142 : if (pFieldmark)
709 3 : bCommentrangeMark = pFieldmark->GetFieldname() == ODF_COMMENTRANGE;
710 : }
711 : }
712 :
713 12142 : if (!bRet)
714 : {
715 : // Unhandled fieldmarks case shouldn't be edited manually to avoid breaking anything
716 12142 : if ( ( pA == pB ) && bUnhandledMark )
717 0 : bRet = true;
718 : // Allow editing of commented ranges.
719 12142 : else if (!bCommentrangeMark)
720 : {
721 : // Form protection case
722 12141 : bool bAtStartA = pA != NULL && pA->GetMarkStart() == *GetPoint();
723 12141 : bool bAtStartB = pB != NULL && pB->GetMarkStart() == *GetMark();
724 12141 : bRet = ( pA != pB ) || bAtStartA || bAtStartB;
725 12141 : bool bProtectForm = pDoc->get( IDocumentSettingAccess::PROTECT_FORM );
726 12141 : if ( bProtectForm )
727 0 : bRet |= ( pA == NULL || pB == NULL );
728 : }
729 : }
730 : else
731 : {
732 0 : bRet = !( pA == pB && pA != NULL );
733 : }
734 :
735 : // Don't allow inserting characters between the 'field mark end' and
736 : // the 'comment anchor', unless the cursor is inside the annotation.
737 12142 : if (!bRet && !bAnnotationMode)
738 : {
739 12140 : if (!pA && GetPoint() && GetPoint()->nNode.GetNode().IsTxtNode() && GetPoint()->nContent.GetIndex() > 0)
740 : {
741 : // getFieldmarkFor() searches for >= start and < end, so check for
742 : // the previous character, to also get the fieldmark, if we're
743 : // exactly at the end.
744 8543 : SwPosition aPrevChar(*GetPoint());
745 8543 : aPrevChar.nContent--;
746 8543 : sw::mark::IFieldmark* pFieldmark = pMarksAccess->getFieldmarkFor(aPrevChar);
747 8543 : if (pFieldmark && pFieldmark->GetMarkEnd() == *GetPoint())
748 1 : bRet = true;
749 : }
750 : }
751 :
752 12142 : return bRet;
753 : }
754 :
755 : /// This function returns the next node in direction of search. If there is no
756 : /// left or the next is out of the area, then a null-pointer is returned.
757 : /// @param rbFirst If <true> than first time request. If so than the position of
758 : /// the PaM must not be changed!
759 302 : SwCntntNode* GetNode( SwPaM & rPam, sal_Bool& rbFirst, SwMoveFn fnMove,
760 : sal_Bool bInReadOnly )
761 : {
762 302 : SwCntntNode * pNd = 0;
763 : SwCntntFrm* pFrm;
764 605 : if( ((*rPam.GetPoint()).*fnMove->fnCmpOp)( *rPam.GetMark() ) ||
765 4 : ( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) )
766 : {
767 301 : if( rbFirst )
768 : {
769 90 : rbFirst = sal_False;
770 90 : pNd = rPam.GetCntntNode();
771 90 : if( pNd )
772 : {
773 90 : if(
774 : (
775 180 : 0 == ( pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout() ) ) ||
776 136 : ( !bInReadOnly && pFrm->IsProtected() ) ||
777 180 : (pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow())
778 180 : ) ||
779 68 : ( !bInReadOnly && pNd->FindSectionNode() &&
780 22 : pNd->FindSectionNode()->GetSection().IsProtect()
781 : )
782 : )
783 : {
784 0 : pNd = 0;
785 : }
786 : }
787 : }
788 :
789 301 : if( !pNd ) // is the cursor not on a CntntNode?
790 : {
791 211 : SwPosition aPos( *rPam.GetPoint() );
792 211 : sal_Bool bSrchForward = fnMove == fnMoveForward;
793 211 : SwNodes& rNodes = aPos.nNode.GetNodes();
794 :
795 : // go to next/previous CntntNode
796 : while( true )
797 : {
798 : pNd = bSrchForward
799 211 : ? rNodes.GoNextSection( &aPos.nNode, sal_True, !bInReadOnly )
800 422 : : rNodes.GoPrevSection( &aPos.nNode, sal_True, !bInReadOnly );
801 211 : if( pNd )
802 : {
803 211 : aPos.nContent.Assign( pNd, ::GetSttOrEnd( bSrchForward,*pNd ));
804 : // is the position still in the area
805 211 : if( (aPos.*fnMove->fnCmpOp)( *rPam.GetMark() ) )
806 : {
807 : // only in AutoTextSection can be nodes that are hidden
808 618 : if( 0 == ( pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout() ) ) ||
809 492 : ( !bInReadOnly && pFrm->IsProtected() ) ||
810 408 : ( pFrm->IsTxtFrm() &&
811 202 : ((SwTxtFrm*)pFrm)->IsHiddenNow() ) )
812 : {
813 0 : pNd = 0;
814 0 : continue;
815 : }
816 206 : *(SwPosition*)rPam.GetPoint() = aPos;
817 : }
818 : else
819 5 : pNd = 0; // no valid node
820 211 : break;
821 : }
822 0 : break;
823 211 : }
824 : }
825 : }
826 302 : return pNd;
827 : }
828 :
829 :
830 8395 : void GoStartDoc( SwPosition * pPos )
831 : {
832 8395 : SwNodes& rNodes = pPos->nNode.GetNodes();
833 8395 : pPos->nNode = *rNodes.GetEndOfContent().StartOfSectionNode();
834 : // we always need to find a ContentNode!
835 8395 : SwCntntNode* pCNd = rNodes.GoNext( &pPos->nNode );
836 8395 : if( pCNd )
837 8395 : pCNd->MakeStartIndex( &pPos->nContent );
838 8395 : }
839 :
840 :
841 3740 : void GoEndDoc( SwPosition * pPos )
842 : {
843 3740 : SwNodes& rNodes = pPos->nNode.GetNodes();
844 3740 : pPos->nNode = rNodes.GetEndOfContent();
845 3740 : SwCntntNode* pCNd = GoPreviousNds( &pPos->nNode, sal_True );
846 3740 : if( pCNd )
847 3740 : pCNd->MakeEndIndex( &pPos->nContent );
848 3740 : }
849 :
850 :
851 0 : void GoStartSection( SwPosition * pPos )
852 : {
853 : // jump to section's beginning
854 0 : SwNodes& rNodes = pPos->nNode.GetNodes();
855 0 : sal_uInt16 nLevel = rNodes.GetSectionLevel( pPos->nNode );
856 0 : if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() )
857 0 : nLevel--;
858 0 : do { rNodes.GoStartOfSection( &pPos->nNode ); } while( nLevel-- );
859 :
860 : // already on a CntntNode
861 0 : pPos->nNode.GetNode().GetCntntNode()->MakeStartIndex( &pPos->nContent );
862 0 : }
863 :
864 : /// go to the end of the current base section
865 0 : void GoEndSection( SwPosition * pPos )
866 : {
867 : // jump to section's beginning/end
868 0 : SwNodes& rNodes = pPos->nNode.GetNodes();
869 0 : sal_uInt16 nLevel = rNodes.GetSectionLevel( pPos->nNode );
870 0 : if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() )
871 0 : nLevel--;
872 0 : do { rNodes.GoEndOfSection( &pPos->nNode ); } while( nLevel-- );
873 :
874 : // now on a EndNode, thus to the previous CntntNode
875 0 : if( GoPreviousNds( &pPos->nNode, sal_True ) )
876 0 : pPos->nNode.GetNode().GetCntntNode()->MakeEndIndex( &pPos->nContent );
877 0 : }
878 :
879 :
880 :
881 12135 : bool GoInDoc( SwPaM & rPam, SwMoveFn fnMove )
882 : {
883 12135 : (*fnMove->fnDoc)( rPam.GetPoint() );
884 12135 : return true;
885 : }
886 :
887 :
888 0 : bool GoInSection( SwPaM & rPam, SwMoveFn fnMove )
889 : {
890 0 : (*fnMove->fnSections)( (SwPosition*)rPam.GetPoint() );
891 0 : return true;
892 : }
893 :
894 :
895 24282 : bool GoInNode( SwPaM & rPam, SwMoveFn fnMove )
896 : {
897 24282 : SwCntntNode *pNd = (*fnMove->fnNds)( &rPam.GetPoint()->nNode, sal_True );
898 24282 : if( pNd )
899 21656 : rPam.GetPoint()->nContent.Assign( pNd,
900 43312 : ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
901 24282 : return pNd;
902 : }
903 :
904 :
905 84070 : bool GoInCntnt( SwPaM & rPam, SwMoveFn fnMove )
906 : {
907 168140 : if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
908 168140 : &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS ))
909 81058 : return true;
910 3012 : return GoInNode( rPam, fnMove );
911 : }
912 :
913 0 : bool GoInCntntCells( SwPaM & rPam, SwMoveFn fnMove )
914 : {
915 0 : if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
916 0 : &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS ))
917 0 : return true;
918 0 : return GoInNode( rPam, fnMove );
919 : }
920 :
921 17 : bool GoInCntntSkipHidden( SwPaM & rPam, SwMoveFn fnMove )
922 : {
923 34 : if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
924 34 : &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS | CRSR_SKIP_HIDDEN ) )
925 15 : return true;
926 2 : return GoInNode( rPam, fnMove );
927 : }
928 :
929 0 : bool GoInCntntCellsSkipHidden( SwPaM & rPam, SwMoveFn fnMove )
930 : {
931 0 : if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
932 0 : &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS | CRSR_SKIP_HIDDEN ) )
933 0 : return true;
934 0 : return GoInNode( rPam, fnMove );
935 : }
936 :
937 :
938 :
939 :
940 :
941 8 : sal_Bool GoPrevPara( SwPaM & rPam, SwPosPara aPosPara )
942 : {
943 8 : if( rPam.Move( fnMoveBackward, fnGoNode ) )
944 : {
945 : // always on a CntntNode
946 8 : SwPosition& rPos = *rPam.GetPoint();
947 8 : SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
948 : rPos.nContent.Assign( pNd,
949 8 : ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ) );
950 8 : return sal_True;
951 : }
952 0 : return sal_False;
953 : }
954 :
955 :
956 1809 : sal_Bool GoCurrPara( SwPaM & rPam, SwPosPara aPosPara )
957 : {
958 1809 : SwPosition& rPos = *rPam.GetPoint();
959 1809 : SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
960 1809 : if( pNd )
961 : {
962 1809 : xub_StrLen nOld = rPos.nContent.GetIndex(),
963 1809 : nNew = aPosPara == fnMoveForward ? 0 : pNd->Len();
964 : // if already at beginning/end then to the next/previous
965 1809 : if( nOld != nNew )
966 : {
967 1809 : rPos.nContent.Assign( pNd, nNew );
968 1809 : return sal_True;
969 : }
970 : }
971 : // move node to next/previous CntntNode
972 0 : if( ( aPosPara==fnParaStart && 0 != ( pNd =
973 0 : GoPreviousNds( &rPos.nNode, sal_True ))) ||
974 0 : ( aPosPara==fnParaEnd && 0 != ( pNd =
975 0 : GoNextNds( &rPos.nNode, sal_True ))) )
976 : {
977 : rPos.nContent.Assign( pNd,
978 0 : ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ));
979 0 : return sal_True;
980 : }
981 0 : return sal_False;
982 : }
983 :
984 :
985 1826 : sal_Bool GoNextPara( SwPaM & rPam, SwPosPara aPosPara )
986 : {
987 1826 : if( rPam.Move( fnMoveForward, fnGoNode ) )
988 : {
989 : // always on a CntntNode
990 1173 : SwPosition& rPos = *rPam.GetPoint();
991 1173 : SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
992 : rPos.nContent.Assign( pNd,
993 1173 : ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ) );
994 1173 : return sal_True;
995 : }
996 653 : return sal_False;
997 : }
998 :
999 :
1000 :
1001 1979 : sal_Bool GoCurrSection( SwPaM & rPam, SwMoveFn fnMove )
1002 : {
1003 1979 : SwPosition& rPos = *rPam.GetPoint();
1004 1979 : SwPosition aSavePos( rPos ); // position for comparison
1005 1979 : SwNodes& rNds = aSavePos.nNode.GetNodes();
1006 1979 : (rNds.*fnMove->fnSection)( &rPos.nNode );
1007 : SwCntntNode *pNd;
1008 3352 : if( 0 == ( pNd = rPos.nNode.GetNode().GetCntntNode()) &&
1009 1373 : 0 == ( pNd = (*fnMove->fnNds)( &rPos.nNode, sal_True )) )
1010 : {
1011 0 : rPos = aSavePos; // do not change cursor
1012 0 : return sal_False;
1013 : }
1014 :
1015 : rPos.nContent.Assign( pNd,
1016 1979 : ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
1017 1979 : return aSavePos != rPos;
1018 : }
1019 :
1020 :
1021 0 : sal_Bool GoNextSection( SwPaM & rPam, SwMoveFn fnMove )
1022 : {
1023 0 : SwPosition& rPos = *rPam.GetPoint();
1024 0 : SwPosition aSavePos( rPos ); // position for comparison
1025 0 : SwNodes& rNds = aSavePos.nNode.GetNodes();
1026 0 : rNds.GoEndOfSection( &rPos.nNode );
1027 :
1028 : // no other CntntNode existent?
1029 0 : if( !GoInCntnt( rPam, fnMoveForward ) )
1030 : {
1031 0 : rPos = aSavePos; // do not change cursor
1032 0 : return sal_False;
1033 : }
1034 0 : (rNds.*fnMove->fnSection)( &rPos.nNode );
1035 0 : SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
1036 : rPos.nContent.Assign( pNd,
1037 0 : ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
1038 0 : return sal_True;
1039 : }
1040 :
1041 :
1042 0 : sal_Bool GoPrevSection( SwPaM & rPam, SwMoveFn fnMove )
1043 : {
1044 0 : SwPosition& rPos = *rPam.GetPoint();
1045 0 : SwPosition aSavePos( rPos ); // position for comparison
1046 0 : SwNodes& rNds = aSavePos.nNode.GetNodes();
1047 0 : rNds.GoStartOfSection( &rPos.nNode );
1048 :
1049 : // no further CntntNode existent?
1050 0 : if( !GoInCntnt( rPam, fnMoveBackward ))
1051 : {
1052 0 : rPos = aSavePos; // do not change cursor
1053 0 : return sal_False;
1054 : }
1055 0 : (rNds.*fnMove->fnSection)( &rPos.nNode );
1056 0 : SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
1057 : rPos.nContent.Assign( pNd,
1058 0 : ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ));
1059 0 : return sal_True;
1060 : }
1061 :
1062 7 : OUString SwPaM::GetTxt() const
1063 : {
1064 7 : OUString aResult;
1065 :
1066 14 : SwNodeIndex aNodeIndex = Start()->nNode;
1067 :
1068 : // The first node can be already the end node.
1069 : // Use a "forever" loop with an exit condition in the middle
1070 : // of its body, in order to correctly handle all cases.
1071 7 : bool bIsStartNode = true;
1072 : for (;;)
1073 : {
1074 7 : const bool bIsEndNode = aNodeIndex == End()->nNode;
1075 7 : SwTxtNode * pTxtNode = aNodeIndex.GetNode().GetTxtNode();
1076 :
1077 7 : if (pTxtNode != NULL)
1078 : {
1079 7 : const OUString aTmpStr = pTxtNode->GetTxt();
1080 :
1081 7 : if (bIsStartNode || bIsEndNode)
1082 : {
1083 : // Handle corner cases of start/end node(s)
1084 : const sal_Int32 nStart = bIsStartNode
1085 7 : ? static_cast<sal_Int32>(Start()->nContent.GetIndex())
1086 14 : : 0;
1087 : const sal_Int32 nEnd = bIsEndNode
1088 7 : ? static_cast<sal_Int32>(End()->nContent.GetIndex())
1089 14 : : aTmpStr.getLength();
1090 :
1091 7 : aResult += aTmpStr.copy(nStart, nEnd-nStart);
1092 : }
1093 : else
1094 : {
1095 0 : aResult += aTmpStr;
1096 7 : }
1097 : }
1098 :
1099 7 : if (bIsEndNode)
1100 : {
1101 7 : break;
1102 : }
1103 :
1104 0 : ++aNodeIndex;
1105 0 : bIsStartNode = false;
1106 0 : }
1107 :
1108 14 : return aResult;
1109 : }
1110 :
1111 0 : void SwPaM::InvalidatePaM()
1112 : {
1113 0 : const SwNode *_pNd=this->GetNode();
1114 0 : const SwTxtNode *_pTxtNd=(_pNd!=NULL?_pNd->GetTxtNode():NULL);
1115 0 : if (_pTxtNd!=NULL)
1116 : {
1117 : // pretent that the PaM marks inserted text to recalc the portion...
1118 0 : SwInsTxt aHint( Start()->nContent.GetIndex(),
1119 0 : End()->nContent.GetIndex() - Start()->nContent.GetIndex() + 1 );
1120 0 : SwModify *_pModify=(SwModify*)_pTxtNd;
1121 0 : _pModify->ModifyNotification( 0, &aHint);
1122 : }
1123 99 : }
1124 :
1125 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|