xref: /trunk/main/sw/source/core/crsr/pam.cxx (revision 23d8f725) !
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 #include <hintids.hxx>
29 #include <editeng/protitem.hxx>
30 #include <cntfrm.hxx>
31 #include <pagefrm.hxx>
32 #include <doc.hxx>
33 #include <docary.hxx>
34 #include <pam.hxx>
35 #include <pamtyp.hxx>
36 #include <txtfrm.hxx>
37 #include <section.hxx>
38 #include <fmtcntnt.hxx>
39 #include <frmatr.hxx>
40 #include <swtable.hxx>
41 #include <crsskip.hxx>
42 
43 // --> FME 2004-06-29 #114856# Formular view
44 #include <flyfrm.hxx>
45 #include <fmteiro.hxx>
46 #include <section.hxx>
47 #include <sectfrm.hxx>
48 // <--
49 #include <ndtxt.hxx> // #111827#
50 
51 #include <IMark.hxx>
52 #include <hints.hxx>
53 
54 // fuer den dummen ?MSC-? Compiler
GetSttOrEnd(sal_Bool bCondition,const SwCntntNode & rNd)55 inline xub_StrLen GetSttOrEnd( sal_Bool bCondition, const SwCntntNode& rNd )
56 {
57     return bCondition ? 0 : rNd.Len();
58 }
59 
60 /*************************************************************************
61 |*
62 |*  SwPosition
63 |*
64 |*  Beschreibung        PAM.DOC
65 |*  Ersterstellung      VB  4.3.91
66 |*  Letzte Aenderung    VB  4.3.91
67 |*
68 *************************************************************************/
69 
70 
SwPosition(const SwNodeIndex & rNodeIndex,const SwIndex & rCntnt)71 SwPosition::SwPosition( const SwNodeIndex & rNodeIndex, const SwIndex & rCntnt )
72     : nNode( rNodeIndex ), nContent( rCntnt )
73 {
74 }
75 
SwPosition(const SwNodeIndex & rNodeIndex)76 SwPosition::SwPosition( const SwNodeIndex & rNodeIndex )
77     : nNode( rNodeIndex ), nContent( nNode.GetNode().GetCntntNode() )
78 {
79 }
80 
SwPosition(const SwNode & rNode)81 SwPosition::SwPosition( const SwNode& rNode )
82     : nNode( rNode ), nContent( nNode.GetNode().GetCntntNode() )
83 {
84 }
85 
SwPosition(SwCntntNode & rNode,const xub_StrLen nOffset)86 SwPosition::SwPosition( SwCntntNode & rNode, const xub_StrLen nOffset )
87     : nNode( rNode ), nContent( &rNode, nOffset )
88 {
89 }
90 
91 
SwPosition(const SwPosition & rPos)92 SwPosition::SwPosition( const SwPosition & rPos )
93     : nNode( rPos.nNode ), nContent( rPos.nContent )
94 {
95 }
96 
operator =(const SwPosition & rPos)97 SwPosition &SwPosition::operator=(const SwPosition &rPos)
98 {
99     nNode = rPos.nNode;
100     nContent = rPos.nContent;
101     return *this;
102 }
103 
104 
operator <(const SwPosition & rPos) const105 sal_Bool SwPosition::operator<(const SwPosition &rPos) const
106 {
107     if( nNode < rPos.nNode )
108         return sal_True;
109     if( nNode == rPos.nNode )
110         return ( nContent < rPos.nContent );
111     return sal_False;
112 }
113 
114 
operator >(const SwPosition & rPos) const115 sal_Bool SwPosition::operator>(const SwPosition &rPos) const
116 {
117     if(nNode > rPos.nNode )
118         return sal_True;
119     if( nNode == rPos.nNode )
120         return ( nContent > rPos.nContent );
121     return sal_False;
122 }
123 
124 
operator <=(const SwPosition & rPos) const125 sal_Bool SwPosition::operator<=(const SwPosition &rPos) const
126 {
127     if(nNode < rPos.nNode )
128         return sal_True;
129     if( nNode == rPos.nNode )
130         return ( nContent <= rPos.nContent );
131     return sal_False;
132 }
133 
134 
operator >=(const SwPosition & rPos) const135 sal_Bool SwPosition::operator>=(const SwPosition &rPos) const
136 {
137     if(nNode > rPos.nNode )
138         return sal_True;
139     if( nNode == rPos.nNode )
140         return ( nContent >= rPos.nContent );
141     return sal_False;
142 }
143 
144 
operator ==(const SwPosition & rPos) const145 sal_Bool SwPosition::operator==(const SwPosition &rPos) const
146 {
147     return
148         ( ( nNode == rPos.nNode ) && ( nContent == rPos.nContent ) ?
149             sal_True: sal_False);
150 }
151 
152 
operator !=(const SwPosition & rPos) const153 sal_Bool SwPosition::operator!=(const SwPosition &rPos) const
154 {
155     if( nNode != rPos.nNode )
156         return sal_True;
157     return ( nContent != rPos.nContent );
158 }
159 
GetDoc() const160 SwDoc * SwPosition::GetDoc() const
161 {
162     return nNode.GetNode().GetDoc();
163 }
164 
ComparePosition(const SwPosition & rStt1,const SwPosition & rEnd1,const SwPosition & rStt2,const SwPosition & rEnd2)165 SwComparePosition ComparePosition(
166             const SwPosition& rStt1, const SwPosition& rEnd1,
167             const SwPosition& rStt2, const SwPosition& rEnd2 )
168 {
169     SwComparePosition nRet;
170     if( rStt1 < rStt2 )
171     {
172         if( rEnd1 > rStt2 )
173         {
174             if( rEnd1 >= rEnd2 )
175                 nRet = POS_OUTSIDE;
176             else
177                 nRet = POS_OVERLAP_BEFORE;
178 
179         }
180         else if( rEnd1 == rStt2 )
181             nRet = POS_COLLIDE_END;
182         else
183             nRet = POS_BEFORE;
184     }
185     else if( rEnd2 > rStt1 )
186     {
187         if( rEnd2 >= rEnd1 )
188         {
189             if( rEnd2 == rEnd1 && rStt2 == rStt1 )
190                 nRet = POS_EQUAL;
191             else
192                 nRet = POS_INSIDE;
193         }
194         else
195         {
196             if (rStt1 == rStt2)
197                 nRet = POS_OUTSIDE;
198             else
199                 nRet = POS_OVERLAP_BEHIND;
200         }
201     }
202     else if( rEnd2 == rStt1 )
203         nRet = POS_COLLIDE_START;
204     else
205         nRet = POS_BEHIND;
206     return nRet;
207 }
208 
ComparePosition(const unsigned long nStt1,const unsigned long nEnd1,const unsigned long nStt2,const unsigned long nEnd2)209 SwComparePosition ComparePosition(
210             const unsigned long nStt1, const unsigned long nEnd1,
211             const unsigned long nStt2, const unsigned long nEnd2 )
212 {
213     SwComparePosition nRet;
214     if( nStt1 < nStt2 )
215     {
216         if( nEnd1 > nStt2 )
217         {
218             if( nEnd1 >= nEnd2 )
219                 nRet = POS_OUTSIDE;
220             else
221                 nRet = POS_OVERLAP_BEFORE;
222 
223         }
224         else if( nEnd1 == nStt2 )
225             nRet = POS_COLLIDE_END;
226         else
227             nRet = POS_BEFORE;
228     }
229     else if( nEnd2 > nStt1 )
230     {
231         if( nEnd2 >= nEnd1 )
232         {
233             if( nEnd2 == nEnd1 && nStt2 == nStt1 )
234                 nRet = POS_EQUAL;
235             else
236                 nRet = POS_INSIDE;
237         }
238         else
239         {
240             if (nStt1 == nStt2)
241                 nRet = POS_OUTSIDE;
242             else
243                 nRet = POS_OVERLAP_BEHIND;
244         }
245     }
246     else if( nEnd2 == nStt1 )
247         nRet = POS_COLLIDE_START;
248     else
249         nRet = POS_BEHIND;
250     return nRet;
251 }
252 
253 /*  */
254 
255 enum CHKSECTION { Chk_Both, Chk_One, Chk_None };
256 
257 
lcl_TstIdx(sal_uLong nSttIdx,sal_uLong nEndIdx,const SwNode & rEndNd)258 CHKSECTION lcl_TstIdx( sal_uLong nSttIdx, sal_uLong nEndIdx, const SwNode& rEndNd )
259 {
260     sal_uLong nStt = rEndNd.StartOfSectionIndex(), nEnd = rEndNd.GetIndex();
261     CHKSECTION eSec = nStt < nSttIdx && nEnd >= nSttIdx ? Chk_One : Chk_None;
262     if( nStt < nEndIdx && nEnd >= nEndIdx )
263         return( eSec == Chk_One ? Chk_Both : Chk_One );
264     return eSec;
265 }
266 
267 
lcl_ChkOneRange(CHKSECTION eSec,sal_Bool bChkSections,const SwNode & rBaseEnd,sal_uLong nStt,sal_uLong nEnd)268 sal_Bool lcl_ChkOneRange( CHKSECTION eSec, sal_Bool bChkSections,
269                     const SwNode& rBaseEnd, sal_uLong nStt, sal_uLong nEnd )
270 {
271     if( eSec != Chk_Both )
272         return sal_False;
273 
274     if( !bChkSections )
275         return sal_True;
276 
277     // suche die umspannende Section
278     const SwNodes& rNds = rBaseEnd.GetNodes();
279     const SwNode *pTmp, *pNd = rNds[ nStt ];
280     if( !pNd->IsStartNode() )
281         pNd = pNd->StartOfSectionNode();
282 
283     if( pNd == rNds[ nEnd ]->StartOfSectionNode() )
284         return sal_True;        // der gleiche StartNode, die selbe Section
285 
286     // steht schon auf einem GrundSection Node ? Fehler !!!
287     if( !pNd->StartOfSectionIndex() )
288         return sal_False;
289 
290     while( ( pTmp = pNd->StartOfSectionNode())->EndOfSectionNode() !=
291             &rBaseEnd )
292         pNd = pTmp;
293 
294     sal_uLong nSttIdx = pNd->GetIndex(), nEndIdx = pNd->EndOfSectionIndex();
295     return nSttIdx <= nStt && nStt <= nEndIdx &&
296            nSttIdx <= nEnd && nEnd <= nEndIdx ? sal_True : sal_False;
297 }
298 
299 
CheckNodesRange(const SwNodeIndex & rStt,const SwNodeIndex & rEnd,sal_Bool bChkSection)300 sal_Bool CheckNodesRange( const SwNodeIndex& rStt,
301                         const SwNodeIndex& rEnd, sal_Bool bChkSection )
302 {
303     const SwNodes& rNds = rStt.GetNodes();
304     sal_uLong nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex();
305     CHKSECTION eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfContent() );
306     if( Chk_None != eSec ) return eSec == Chk_Both ? sal_True : sal_False;
307 
308     eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfAutotext() );
309     if( Chk_None != eSec )
310         return lcl_ChkOneRange( eSec, bChkSection,
311                             rNds.GetEndOfAutotext(), nStt, nEnd );
312 
313     eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfPostIts() );
314     if( Chk_None != eSec )
315         return lcl_ChkOneRange( eSec, bChkSection,
316                             rNds.GetEndOfPostIts(), nStt, nEnd );
317 
318     eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfInserts() );
319     if( Chk_None != eSec )
320         return lcl_ChkOneRange( eSec, bChkSection,
321                             rNds.GetEndOfInserts(), nStt, nEnd );
322 
323     eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfRedlines() );
324     if( Chk_None != eSec )
325         return lcl_ChkOneRange( eSec, bChkSection,
326                             rNds.GetEndOfRedlines(), nStt, nEnd );
327 
328     return sal_False;       // liegt irgendwo dazwischen, FEHLER
329 }
330 
331 
GoNext(SwNode * pNd,SwIndex * pIdx,sal_uInt16 nMode)332 sal_Bool GoNext(SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode )
333 {
334     if( pNd->IsCntntNode() )
335         return ((SwCntntNode*)pNd)->GoNext( pIdx, nMode );
336     return sal_False;
337 }
338 
339 
GoPrevious(SwNode * pNd,SwIndex * pIdx,sal_uInt16 nMode)340 sal_Bool GoPrevious( SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode )
341 {
342     if( pNd->IsCntntNode() )
343         return ((SwCntntNode*)pNd)->GoPrevious( pIdx, nMode );
344     return sal_False;
345 }
346 
347 
GoNextNds(SwNodeIndex * pIdx,sal_Bool bChk)348 SwCntntNode* GoNextNds( SwNodeIndex* pIdx, sal_Bool bChk )
349 {
350     SwNodeIndex aIdx( *pIdx );
351     SwCntntNode* pNd = aIdx.GetNodes().GoNext( &aIdx );
352     if( pNd )
353     {
354         if( bChk && 1 != aIdx.GetIndex() - pIdx->GetIndex() &&
355             !CheckNodesRange( *pIdx, aIdx, sal_True ) )
356                 pNd = 0;
357         else
358             *pIdx = aIdx;
359     }
360     return pNd;
361 }
362 
363 
GoPreviousNds(SwNodeIndex * pIdx,sal_Bool bChk)364 SwCntntNode* GoPreviousNds( SwNodeIndex * pIdx, sal_Bool bChk )
365 {
366     SwNodeIndex aIdx( *pIdx );
367     SwCntntNode* pNd = aIdx.GetNodes().GoPrevious( &aIdx );
368     if( pNd )
369     {
370         if( bChk && 1 != pIdx->GetIndex() - aIdx.GetIndex() &&
371             !CheckNodesRange( *pIdx, aIdx, sal_True ) )
372                 pNd = 0;
373         else
374             *pIdx = aIdx;
375     }
376     return pNd;
377 }
378 
379 // ----------------------------------------------------------------------
380 
381 /*************************************************************************
382 |*
383 |*  SwPointAndMark
384 |*
385 |*  Beschreibung        PAM.DOC
386 |*  Ersterstellung      VB  4.3.91
387 |*  Letzte Aenderung    JP  6.5.91
388 |*
389 *************************************************************************/
390 
SwPaM(const SwPosition & rPos,SwPaM * pRing)391 SwPaM::SwPaM( const SwPosition& rPos, SwPaM* pRing )
392     : Ring( pRing )
393     , m_Bound1( rPos )
394     , m_Bound2( rPos.nNode.GetNode().GetNodes() ) // default initialize
395     , m_pPoint( &m_Bound1 )
396     , m_pMark( m_pPoint )
397     , m_bIsInFrontOfLabel( false )
398 {
399 }
400 
SwPaM(const SwPosition & rMark,const SwPosition & rPoint,SwPaM * pRing)401 SwPaM::SwPaM( const SwPosition& rMark, const SwPosition& rPoint, SwPaM* pRing )
402     : Ring( pRing )
403     , m_Bound1( rMark )
404     , m_Bound2( rPoint )
405     , m_pPoint( &m_Bound2 )
406     , m_pMark( &m_Bound1 )
407     , m_bIsInFrontOfLabel( false )
408 {
409 }
410 
SwPaM(const SwNodeIndex & rMark,const SwNodeIndex & rPoint,long nMarkOffset,long nPointOffset,SwPaM * pRing)411 SwPaM::SwPaM( const SwNodeIndex& rMark, const SwNodeIndex& rPoint,
412               long nMarkOffset, long nPointOffset, SwPaM* pRing )
413     : Ring( pRing )
414     , m_Bound1( rMark )
415     , m_Bound2( rPoint )
416     , m_pPoint( &m_Bound2 )
417     , m_pMark( &m_Bound1 )
418     , m_bIsInFrontOfLabel( false )
419 {
420     if ( nMarkOffset )
421     {
422         m_pMark->nNode += nMarkOffset;
423     }
424     if ( nPointOffset )
425     {
426         m_pPoint->nNode += nPointOffset;
427     }
428 
429     m_Bound1.nContent.Assign( m_Bound1.nNode.GetNode().GetCntntNode(), 0 );
430     m_Bound2.nContent.Assign( m_Bound2.nNode.GetNode().GetCntntNode(), 0 );
431 }
432 
SwPaM(const SwNode & rMark,const SwNode & rPoint,long nMarkOffset,long nPointOffset,SwPaM * pRing)433 SwPaM::SwPaM( const SwNode& rMark, const SwNode& rPoint,
434               long nMarkOffset, long nPointOffset, SwPaM* pRing )
435     : Ring( pRing )
436     , m_Bound1( rMark )
437     , m_Bound2( rPoint )
438     , m_pPoint( &m_Bound2 )
439     , m_pMark( &m_Bound1 )
440     , m_bIsInFrontOfLabel( false )
441 {
442     if ( nMarkOffset )
443     {
444         m_pMark->nNode += nMarkOffset;
445     }
446     if ( nPointOffset )
447     {
448         m_pPoint->nNode += nPointOffset;
449     }
450 
451     m_Bound1.nContent.Assign( m_Bound1.nNode.GetNode().GetCntntNode(), 0 );
452     m_Bound2.nContent.Assign( m_Bound2.nNode.GetNode().GetCntntNode(), 0 );
453 }
454 
SwPaM(const SwNodeIndex & rMark,xub_StrLen nMarkCntnt,const SwNodeIndex & rPoint,xub_StrLen nPointCntnt,SwPaM * pRing)455 SwPaM::SwPaM( const SwNodeIndex& rMark , xub_StrLen nMarkCntnt,
456               const SwNodeIndex& rPoint, xub_StrLen nPointCntnt, SwPaM* pRing )
457     : Ring( pRing )
458     , m_Bound1( rMark )
459     , m_Bound2( rPoint )
460     , m_pPoint( &m_Bound2 )
461     , m_pMark( &m_Bound1 )
462     , m_bIsInFrontOfLabel( false )
463 {
464     m_pPoint->nContent.Assign( rPoint.GetNode().GetCntntNode(), nPointCntnt);
465     m_pMark ->nContent.Assign( rMark .GetNode().GetCntntNode(), nMarkCntnt );
466 }
467 
SwPaM(const SwNode & rMark,xub_StrLen nMarkCntnt,const SwNode & rPoint,xub_StrLen nPointCntnt,SwPaM * pRing)468 SwPaM::SwPaM( const SwNode& rMark , xub_StrLen nMarkCntnt,
469               const SwNode& rPoint, xub_StrLen nPointCntnt, SwPaM* pRing )
470     : Ring( pRing )
471     , m_Bound1( rMark )
472     , m_Bound2( rPoint )
473     , m_pPoint( &m_Bound2 )
474     , m_pMark( &m_Bound1 )
475     , m_bIsInFrontOfLabel( false )
476 {
477     m_pPoint->nContent.Assign( m_pPoint->nNode.GetNode().GetCntntNode(),
478         nPointCntnt);
479     m_pMark ->nContent.Assign( m_pMark ->nNode.GetNode().GetCntntNode(),
480         nMarkCntnt );
481 }
482 
SwPaM(const SwNode & rNode,xub_StrLen nCntnt,SwPaM * pRing)483 SwPaM::SwPaM( const SwNode& rNode, xub_StrLen nCntnt, SwPaM* pRing )
484     : Ring( pRing )
485     , m_Bound1( rNode )
486     , m_Bound2( m_Bound1.nNode.GetNode().GetNodes() ) // default initialize
487     , m_pPoint( &m_Bound1 )
488     , m_pMark( &m_Bound1 )
489     , m_bIsInFrontOfLabel( false )
490 {
491     m_pPoint->nContent.Assign( m_pPoint->nNode.GetNode().GetCntntNode(),
492         nCntnt );
493 }
494 
SwPaM(const SwNodeIndex & rNodeIdx,xub_StrLen nCntnt,SwPaM * pRing)495 SwPaM::SwPaM( const SwNodeIndex& rNodeIdx, xub_StrLen nCntnt, SwPaM* pRing )
496     : Ring( pRing )
497     , m_Bound1( rNodeIdx )
498     , m_Bound2( rNodeIdx.GetNode().GetNodes() ) // default initialize
499     , m_pPoint( &m_Bound1 )
500     , m_pMark( &m_Bound1 )
501     , m_bIsInFrontOfLabel( false )
502 {
503     m_pPoint->nContent.Assign( rNodeIdx.GetNode().GetCntntNode(), nCntnt );
504 }
505 
~SwPaM()506 SwPaM::~SwPaM() {}
507 
508 // @@@ semantic: no copy ctor.
SwPaM(SwPaM & rPam)509 SwPaM::SwPaM( SwPaM &rPam )
510     : Ring( &rPam )
511     , m_Bound1( *(rPam.m_pPoint) )
512     , m_Bound2( *(rPam.m_pMark)  )
513     , m_pPoint( &m_Bound1 ), m_pMark( rPam.HasMark() ? &m_Bound2 : m_pPoint )
514     , m_bIsInFrontOfLabel( false )
515 {
516 }
517 
518 // @@@ semantic: no copy assignment for super class Ring.
operator =(const SwPaM & rPam)519 SwPaM &SwPaM::operator=( const SwPaM &rPam )
520 {
521     *m_pPoint = *( rPam.m_pPoint );
522     if ( rPam.HasMark() )
523     {
524         SetMark();
525         *m_pMark = *( rPam.m_pMark );
526     }
527     else
528     {
529         DeleteMark();
530     }
531     return *this;
532 }
533 
SetMark()534 void SwPaM::SetMark()
535 {
536     if (m_pPoint == &m_Bound1)
537     {
538         m_pMark = &m_Bound2;
539     }
540     else
541     {
542         m_pMark = &m_Bound1;
543     }
544     (*m_pMark) = (*m_pPoint);
545 }
546 
547 #ifdef DBG_UTIL
548 
Exchange()549 void SwPaM::Exchange()
550 {
551     if (m_pPoint != m_pMark)
552     {
553         SwPosition *pTmp = m_pPoint;
554         m_pPoint = m_pMark;
555         m_pMark = pTmp;
556     }
557 }
558 #endif
559 
560 // Bewegen des Cursors
561 
562 
Move(SwMoveFn fnMove,SwGoInDoc fnGo)563 sal_Bool SwPaM::Move( SwMoveFn fnMove, SwGoInDoc fnGo )
564 {
565     sal_Bool bRet = (*fnGo)( *this, fnMove );
566 
567     m_bIsInFrontOfLabel = false;
568 
569     return bRet;
570 }
571 
572 
573 /*************************************************************************
574 |*
575 |*    void SwPaM::MakeRegion( SwMoveFn, SwPaM*, const SwPaM* )
576 |*
577 |*    Beschreibung      Setzt den 1. SwPaM auf den uebergebenen SwPaM
578 |*                      oder setzt auf den Anfang oder Ende vom Document.
579 |*                      SPoint bleibt auf der Position stehen, GetMark aendert
580 |*                      sich entsprechend !
581 |*
582 |*    Parameter         SwDirection     gibt an, ob an Anfang / Ende
583 |*                      SwPaM *         der zu setzende Bereich
584 |*                      const SwPaM&    der enventuell vorgegeben Bereich
585 |*    Return-Werte      SwPaM*          der entsprehend neu gesetzte Bereich
586 |*
587 |*    Ersterstellung    JP 26.04.91
588 |*    Letzte Aenderung  JP 26.04.91
589 |*
590 *************************************************************************/
591 
592 
MakeRegion(SwMoveFn fnMove,const SwPaM * pOrigRg)593 SwPaM* SwPaM::MakeRegion( SwMoveFn fnMove, const SwPaM * pOrigRg )
594 {
595     SwPaM* pPam;
596     if( pOrigRg == 0 )
597     {
598         pPam = new SwPaM( *m_pPoint );
599         pPam->SetMark();                    // setze Anfang fest
600         pPam->Move( fnMove, fnGoSection);       // an Anfang / Ende vom Node
601 
602         // stelle SPoint wieder auf alte Position, GetMark auf das "Ende"
603         pPam->Exchange();
604     }
605     else
606     {
607         pPam = new SwPaM( *(SwPaM*)pOrigRg );   // die Suchregion ist vorgegeben
608         // sorge dafuer, dass SPoint auf dem "echten" StartPunkt steht
609         // FORWARD  --> SPoint immer kleiner  als GetMark
610         // BACKWARD --> SPoint immer groesser als GetMark
611         if( (pPam->GetMark()->*fnMove->fnCmpOp)( *pPam->GetPoint() ) )
612             pPam->Exchange();
613     }
614     return pPam;
615 }
616 
Normalize(sal_Bool bPointFirst)617 SwPaM & SwPaM::Normalize(sal_Bool bPointFirst)
618 {
619     if (HasMark())
620         if ( ( bPointFirst && *m_pPoint > *m_pMark) ||
621              (!bPointFirst && *m_pPoint < *m_pMark) )
622         {
623             Exchange();
624         }
625 
626     return *this;
627 }
628 
GetPageNum(sal_Bool bAtPoint,const Point * pLayPos)629 sal_uInt16 SwPaM::GetPageNum( sal_Bool bAtPoint, const Point* pLayPos )
630 {
631     // return die Seitennummer am Cursor
632     // (fuer Reader + Seitengebundene Rahmen)
633     const SwCntntFrm* pCFrm;
634     const SwPageFrm *pPg;
635     const SwCntntNode *pNd ;
636     const SwPosition* pPos = bAtPoint ? m_pPoint : m_pMark;
637 
638     if( 0 != ( pNd = pPos->nNode.GetNode().GetCntntNode() ) &&
639         0 != ( pCFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), pLayPos, pPos, sal_False )) &&
640         0 != ( pPg = pCFrm->FindPageFrm() ))
641         return pPg->GetPhyPageNum();
642     return 0;
643 }
644 
645 // --> FME 2004-06-29 #114856# Formular view
646 // See also SwCrsrShell::IsCrsrReadonly()
lcl_FindEditInReadonlyFrm(const SwFrm & rFrm)647 const SwFrm* lcl_FindEditInReadonlyFrm( const SwFrm& rFrm )
648 {
649     const SwFrm* pRet = 0;
650 
651     const SwFlyFrm* pFly;
652     const SwSectionFrm* pSectionFrm;
653 
654     if( rFrm.IsInFly() &&
655        (pFly = rFrm.FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() &&
656         pFly->Lower() &&
657        !pFly->Lower()->IsNoTxtFrm() )
658     {
659        pRet = pFly;
660     }
661     else if ( rFrm.IsInSct() &&
662               0 != ( pSectionFrm = rFrm.FindSctFrm() )->GetSection() &&
663               pSectionFrm->GetSection()->IsEditInReadonlyFlag() )
664     {
665         pRet = pSectionFrm;
666     }
667 
668     return pRet;
669 }
670 // <--
671 
672 // steht in etwas geschuetztem oder in die Selektion umspannt
673 // etwas geschuetztes.
HasReadonlySel(const bool bFormView) const674 sal_Bool SwPaM::HasReadonlySel( const bool bFormView ) const
675 {
676     sal_Bool bRet = sal_False;
677 
678     const SwCntntNode* pNd = GetPoint()->nNode.GetNode().GetCntntNode();
679     const SwCntntFrm *pFrm = NULL;
680     if ( pNd != NULL )
681     {
682         Point aTmpPt;
683         pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), &aTmpPt, GetPoint(), sal_False );
684     }
685 
686     // Will be set if point are inside edit-in-readonly environment
687     const SwFrm* pPointEditInReadonlyFrm = NULL;
688     if ( pFrm != NULL
689          && ( pFrm->IsProtected()
690               || ( bFormView
691                    && 0 == ( pPointEditInReadonlyFrm = lcl_FindEditInReadonlyFrm( *pFrm ) ) ) ) )
692     {
693         bRet = sal_True;
694     }
695     else if( pNd != NULL )
696     {
697         const SwSectionNode* pSNd = pNd->GetSectionNode();
698         if ( pSNd != NULL
699              && ( pSNd->GetSection().IsProtectFlag()
700                   || ( bFormView
701                        && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
702         {
703             bRet = sal_True;
704         }
705     }
706 
707     if ( !bRet
708          && HasMark()
709          && GetPoint()->nNode != GetMark()->nNode )
710     {
711         pNd = GetMark()->nNode.GetNode().GetCntntNode();
712         pFrm = NULL;
713         if ( pNd != NULL )
714         {
715             Point aTmpPt;
716             pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), &aTmpPt, GetMark(), sal_False );
717         }
718 
719         const SwFrm* pMarkEditInReadonlyFrm = NULL;
720         if ( pFrm != NULL
721              && ( pFrm->IsProtected()
722                   || ( bFormView
723                        && 0 == ( pMarkEditInReadonlyFrm = lcl_FindEditInReadonlyFrm( *pFrm ) ) ) ) )
724         {
725             bRet = sal_True;
726         }
727         else if( pNd != NULL )
728         {
729             const SwSectionNode* pSNd = pNd->GetSectionNode();
730             if ( pSNd != NULL
731                  && ( pSNd->GetSection().IsProtectFlag()
732                       || ( bFormView
733                            && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
734             {
735                 bRet = sal_True;
736             }
737         }
738 
739         if ( !bRet && bFormView )
740         {
741            // Check if start and end frame are inside the _same_
742            // edit-in-readonly-environment. Otherwise we better return 'true'
743            if ( pPointEditInReadonlyFrm != pMarkEditInReadonlyFrm )
744                 bRet = sal_True;
745         }
746 
747         // check for protected section inside the selection
748         if( !bRet )
749         {
750             sal_uLong nSttIdx = GetMark()->nNode.GetIndex(),
751                     nEndIdx = GetPoint()->nNode.GetIndex();
752             if( nEndIdx <= nSttIdx )
753             {
754                 sal_uLong nTmp = nSttIdx;
755                 nSttIdx = nEndIdx;
756                 nEndIdx = nTmp;
757             }
758 
759             // wenn ein geschuetzter Bereich zwischen den Nodes stehen soll,
760             // muss die Selektion selbst schon x Nodes umfassen.
761             // (TxtNd, SectNd, TxtNd, EndNd, TxtNd )
762             if( nSttIdx + 3 < nEndIdx )
763             {
764                 const SwSectionFmts& rFmts = GetDoc()->GetSections();
765                 for( sal_uInt16 n = rFmts.Count(); n;  )
766                 {
767                     const SwSectionFmt* pFmt = rFmts[ --n ];
768                     if( pFmt->GetProtect().IsCntntProtected() )
769                     {
770                         const SwFmtCntnt& rCntnt = pFmt->GetCntnt(sal_False);
771                         ASSERT( rCntnt.GetCntntIdx(), "wo ist der SectionNode?" );
772                         sal_uLong nIdx = rCntnt.GetCntntIdx()->GetIndex();
773                         if( nSttIdx <= nIdx && nEndIdx >= nIdx &&
774                             rCntnt.GetCntntIdx()->GetNode().GetNodes().IsDocNodes() )
775                         {
776                             bRet = sal_True;
777                             break;
778                         }
779                     }
780                 }
781 
782 #ifdef CHECK_CELL_READONLY
783 //JP 22.01.99: bisher wurden Tabelle, die in der Text-Selektion standen
784 //              nicht beachtet. Wollte man das haben, dann muss dieser
785 //              Code freigeschaltet werden
786 
787                 if( !bRet )
788                 {
789                     // dann noch ueber alle Tabellen
790                     const SwFrmFmts& rFmts = *GetDoc()->GetTblFrmFmts();
791                     for( n = rFmts.Count(); n ;  )
792                     {
793                         SwFrmFmt* pFmt = (SwFrmFmt*)rFmts[ --n ];
794                         const SwTable* pTbl = SwTable::FindTable( pFmt );
795                         sal_uLong nIdx = pTbl ? pTbl->GetTabSortBoxes()[0]->GetSttIdx()
796                                           : 0;
797                         if( nSttIdx <= nIdx && nEndIdx >= nIdx )
798                         {
799                             // dann teste mal alle Boxen
800                             const SwTableSortBoxes& rBoxes = pTbl->GetTabSortBoxes();
801 
802                             for( sal_uInt16 i =  rBoxes.Count(); i; )
803                                 if( rBoxes[ --i ]->GetFrmFmt()->GetProtect().
804                                     IsCntntProtected() )
805                                 {
806                                     bRet = sal_True;
807                                     break;
808                                 }
809 
810                             if( bRet )
811                                 break;
812                         }
813                     }
814                 }
815 #endif
816             }
817         }
818     }
819 
820     //FIXME FieldBk
821     // TODO: Form Protection when Enhanced Fields are enabled
822     if (!bRet)
823     {
824         const SwDoc *pDoc = GetDoc();
825         sw::mark::IMark* pA = NULL;
826         sw::mark::IMark* pB = NULL;
827         if ( pDoc )
828         {
829             const IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess( );
830             pA = GetPoint() ? pMarksAccess->getFieldmarkFor( *GetPoint( ) ) : NULL;
831             pB = GetMark( ) ? pMarksAccess->getFieldmarkFor( *GetMark( ) ) : pA;
832             bRet = ( pA != pB );
833         }
834         bool bProtectForm = pDoc->get( IDocumentSettingAccess::PROTECT_FORM );
835         if ( bProtectForm )
836             bRet |= ( pA == NULL || pB == NULL );
837     }
838 
839     return bRet;
840 }
841 
842 //--------------------  Suche nach Formaten( FormatNamen ) -----------------
843 
844 // die Funktion gibt in Suchrichtung den folgenden Node zurueck.
845 // Ist in der Richtung keiner mehr vorhanden oder ist dieser ausserhalb
846 // des Bereiches, wird ein 0 Pointer returnt.
847 // Das rbFirst gibt an, ob es man zu erstenmal einen Node holt. Ist das der
848 // Fall, darf die Position vom Pam nicht veraendert werden!
849 
850 
GetNode(SwPaM & rPam,sal_Bool & rbFirst,SwMoveFn fnMove,sal_Bool bInReadOnly)851 SwCntntNode* GetNode( SwPaM & rPam, sal_Bool& rbFirst, SwMoveFn fnMove,
852                         sal_Bool bInReadOnly )
853 {
854     SwCntntNode * pNd = 0;
855     SwCntntFrm* pFrm;
856     if( ((*rPam.GetPoint()).*fnMove->fnCmpOp)( *rPam.GetMark() ) ||
857         ( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) )
858     {
859         if( rbFirst )
860         {
861             rbFirst = sal_False;
862             pNd = rPam.GetCntntNode();
863             if( pNd )
864             {
865                 if(
866                     (
867                         0 == ( pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout() ) ) ||
868                         ( !bInReadOnly && pFrm->IsProtected() ) ||
869                         (pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow())
870                     ) ||
871                     ( !bInReadOnly && pNd->FindSectionNode() &&
872                         pNd->FindSectionNode()->GetSection().IsProtect()
873                     )
874                   )
875                     {
876                         pNd = 0;
877                     }
878             }
879         }
880 
881         if( !pNd )          // steht Cursor auf keinem ContentNode ?
882         {
883             SwPosition aPos( *rPam.GetPoint() );
884             sal_Bool bSrchForward = fnMove == fnMoveForward;
885             SwNodes& rNodes = aPos.nNode.GetNodes();
886 
887             // zum naechsten / vorherigen ContentNode
888 // Funktioniert noch alles, wenn die Uerbpruefung vom ueberspringen der
889 // Sektions herausgenommen wird ??
890 //          if( (*fnMove->fnNds)( rNodes, &aPos.nNode ) )
891             while( sal_True )
892             {
893                 pNd = bSrchForward
894                         ? rNodes.GoNextSection( &aPos.nNode, sal_True, !bInReadOnly )
895                         : rNodes.GoPrevSection( &aPos.nNode, sal_True, !bInReadOnly );
896                 if( pNd )
897                 {
898                     aPos.nContent.Assign( pNd, ::GetSttOrEnd( bSrchForward,*pNd ));
899                     // liegt Position immer noch im Bereich ?
900                     if( (aPos.*fnMove->fnCmpOp)( *rPam.GetMark() ) )
901                     {
902                         // nur in der AutoTextSection koennen Node stehen, die
903                         // nicht angezeigt werden !!
904                         if( 0 == ( pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout() ) ) ||
905                             ( !bInReadOnly && pFrm->IsProtected() ) ||
906                             ( pFrm->IsTxtFrm() &&
907                                 ((SwTxtFrm*)pFrm)->IsHiddenNow() ) )
908 
909 //                          rNodes[ rNodes.EndOfAutotext ]->StartOfSection().GetIndex()
910 //                          < aPos.nNode.GetIndex() && aPos.nNode.GetIndex()
911 //                          < rNodes.EndOfAutotext.GetIndex() &&
912 //                          0 == ( pFrm = pNd->GetFrm()) &&
913 //                          pFrm->IsProtected() )
914                         {
915                             pNd = 0;
916                             continue;       // suche weiter
917                         }
918                         *(SwPosition*)rPam.GetPoint() = aPos;
919                     }
920                     else
921                         pNd = 0;            // kein gueltiger Node
922                     break;
923                 }
924                 break;
925             }
926         }
927     }
928     return pNd;
929 }
930 
931 // ----------------------------------------------------------------------
932 
933 // hier folgen die Move-Methoden ( Foward, Backward; Content, Node, Doc )
934 
935 
GoStartDoc(SwPosition * pPos)936 void GoStartDoc( SwPosition * pPos )
937 {
938     SwNodes& rNodes = pPos->nNode.GetNodes();
939     pPos->nNode = *rNodes.GetEndOfContent().StartOfSectionNode();
940     // es muss immer ein ContentNode gefunden werden !!
941     SwCntntNode* pCNd = rNodes.GoNext( &pPos->nNode );
942     if( pCNd )
943         pCNd->MakeStartIndex( &pPos->nContent );
944 }
945 
946 
GoEndDoc(SwPosition * pPos)947 void GoEndDoc( SwPosition * pPos )
948 {
949     SwNodes& rNodes = pPos->nNode.GetNodes();
950     pPos->nNode = rNodes.GetEndOfContent();
951     SwCntntNode* pCNd = GoPreviousNds( &pPos->nNode, sal_True );
952     if( pCNd )
953         pCNd->MakeEndIndex( &pPos->nContent );
954 }
955 
956 
GoStartSection(SwPosition * pPos)957 void GoStartSection( SwPosition * pPos )
958 {
959     // springe zum Anfang der Section
960     SwNodes& rNodes = pPos->nNode.GetNodes();
961     sal_uInt16 nLevel = rNodes.GetSectionLevel( pPos->nNode );
962     if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() )
963         nLevel--;
964     do { rNodes.GoStartOfSection( &pPos->nNode ); } while( nLevel-- );
965 
966     // steht jetzt schon auf einem CntntNode
967     pPos->nNode.GetNode().GetCntntNode()->MakeStartIndex( &pPos->nContent );
968 }
969 
970 // gehe an das Ende der akt. Grund-Section
971 
972 
GoEndSection(SwPosition * pPos)973 void GoEndSection( SwPosition * pPos )
974 {
975     // springe zum Anfang/Ende der Section
976     SwNodes& rNodes = pPos->nNode.GetNodes();
977     sal_uInt16 nLevel = rNodes.GetSectionLevel( pPos->nNode );
978     if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() )
979         nLevel--;
980     do { rNodes.GoEndOfSection( &pPos->nNode ); } while( nLevel-- );
981 
982     // steht jetzt auf einem EndNode, also zum vorherigen CntntNode
983     if( GoPreviousNds( &pPos->nNode, sal_True ) )
984         pPos->nNode.GetNode().GetCntntNode()->MakeEndIndex( &pPos->nContent );
985 }
986 
987 
988 
GoInDoc(SwPaM & rPam,SwMoveFn fnMove)989 sal_Bool GoInDoc( SwPaM & rPam, SwMoveFn fnMove )
990 {
991     (*fnMove->fnDoc)( rPam.GetPoint() );
992     return sal_True;
993 }
994 
995 
GoInSection(SwPaM & rPam,SwMoveFn fnMove)996 sal_Bool GoInSection( SwPaM & rPam, SwMoveFn fnMove )
997 {
998     (*fnMove->fnSections)( (SwPosition*)rPam.GetPoint() );
999     return sal_True;
1000 }
1001 
1002 
GoInNode(SwPaM & rPam,SwMoveFn fnMove)1003 sal_Bool GoInNode( SwPaM & rPam, SwMoveFn fnMove )
1004 {
1005     SwCntntNode *pNd = (*fnMove->fnNds)( &rPam.GetPoint()->nNode, sal_True );
1006     if( pNd )
1007         rPam.GetPoint()->nContent.Assign( pNd,
1008                         ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
1009     return 0 != pNd;
1010 }
1011 
1012 
GoInCntnt(SwPaM & rPam,SwMoveFn fnMove)1013 sal_Bool GoInCntnt( SwPaM & rPam, SwMoveFn fnMove )
1014 {
1015     if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
1016                         &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS ))
1017         return sal_True;
1018     return GoInNode( rPam, fnMove );
1019 }
1020 
GoInCntntCells(SwPaM & rPam,SwMoveFn fnMove)1021 sal_Bool GoInCntntCells( SwPaM & rPam, SwMoveFn fnMove )
1022 {
1023     if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
1024                          &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS ))
1025         return sal_True;
1026     return GoInNode( rPam, fnMove );
1027 }
1028 
GoInCntntSkipHidden(SwPaM & rPam,SwMoveFn fnMove)1029 sal_Bool GoInCntntSkipHidden( SwPaM & rPam, SwMoveFn fnMove )
1030 {
1031     if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
1032                         &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS | CRSR_SKIP_HIDDEN ) )
1033         return sal_True;
1034     return GoInNode( rPam, fnMove );
1035 }
1036 
GoInCntntCellsSkipHidden(SwPaM & rPam,SwMoveFn fnMove)1037 sal_Bool GoInCntntCellsSkipHidden( SwPaM & rPam, SwMoveFn fnMove )
1038 {
1039     if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
1040                          &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS | CRSR_SKIP_HIDDEN ) )
1041         return sal_True;
1042     return GoInNode( rPam, fnMove );
1043 }
1044 
1045 
1046 
1047 // --------- Funktionsdefinitionen fuer die SwCrsrShell --------------
1048 
1049 
GoPrevPara(SwPaM & rPam,SwPosPara aPosPara)1050 sal_Bool GoPrevPara( SwPaM & rPam, SwPosPara aPosPara )
1051 {
1052     if( rPam.Move( fnMoveBackward, fnGoNode ) )
1053     {
1054         // steht immer auf einem ContentNode !
1055         SwPosition& rPos = *rPam.GetPoint();
1056         SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
1057         rPos.nContent.Assign( pNd,
1058                             ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ) );
1059         return sal_True;
1060     }
1061     return sal_False;
1062 }
1063 
1064 
GoCurrPara(SwPaM & rPam,SwPosPara aPosPara)1065 sal_Bool GoCurrPara( SwPaM & rPam, SwPosPara aPosPara )
1066 {
1067     SwPosition& rPos = *rPam.GetPoint();
1068     SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
1069     if( pNd )
1070     {
1071         xub_StrLen nOld = rPos.nContent.GetIndex(),
1072                    nNew = aPosPara == fnMoveForward ? 0 : pNd->Len();
1073         // stand er schon auf dem Anfang/Ende dann zum naechsten/vorherigen
1074         if( nOld != nNew )
1075         {
1076             rPos.nContent.Assign( pNd, nNew );
1077             return sal_True;
1078         }
1079     }
1080     // den Node noch etwas bewegen ( auf den naechsten/vorh. CntntNode)
1081     if( ( aPosPara==fnParaStart && 0 != ( pNd =
1082             GoPreviousNds( &rPos.nNode, sal_True ))) ||
1083         ( aPosPara==fnParaEnd && 0 != ( pNd =
1084             GoNextNds( &rPos.nNode, sal_True ))) )
1085     {
1086         rPos.nContent.Assign( pNd,
1087                         ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ));
1088         return sal_True;
1089     }
1090     return sal_False;
1091 }
1092 
1093 
GoNextPara(SwPaM & rPam,SwPosPara aPosPara)1094 sal_Bool GoNextPara( SwPaM & rPam, SwPosPara aPosPara )
1095 {
1096     if( rPam.Move( fnMoveForward, fnGoNode ) )
1097     {
1098         // steht immer auf einem ContentNode !
1099         SwPosition& rPos = *rPam.GetPoint();
1100         SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
1101         rPos.nContent.Assign( pNd,
1102                         ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ) );
1103         return sal_True;
1104     }
1105     return sal_False;
1106 }
1107 
1108 
1109 
GoCurrSection(SwPaM & rPam,SwMoveFn fnMove)1110 sal_Bool GoCurrSection( SwPaM & rPam, SwMoveFn fnMove )
1111 {
1112     SwPosition& rPos = *rPam.GetPoint();
1113     SwPosition aSavePos( rPos );        // eine Vergleichsposition
1114     SwNodes& rNds = aSavePos.nNode.GetNodes();
1115     (rNds.*fnMove->fnSection)( &rPos.nNode );
1116     SwCntntNode *pNd;
1117     if( 0 == ( pNd = rPos.nNode.GetNode().GetCntntNode()) &&
1118         0 == ( pNd = (*fnMove->fnNds)( &rPos.nNode, sal_True )) )
1119     {
1120         rPos = aSavePos;        // Cusror nicht veraendern
1121         return sal_False;
1122     }
1123 
1124     rPos.nContent.Assign( pNd,
1125                         ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
1126     return aSavePos != rPos;
1127 }
1128 
1129 
GoNextSection(SwPaM & rPam,SwMoveFn fnMove)1130 sal_Bool GoNextSection( SwPaM & rPam, SwMoveFn fnMove )
1131 {
1132     SwPosition& rPos = *rPam.GetPoint();
1133     SwPosition aSavePos( rPos );        // eine Vergleichsposition
1134     SwNodes& rNds = aSavePos.nNode.GetNodes();
1135     rNds.GoEndOfSection( &rPos.nNode );
1136 
1137     // kein weiterer ContentNode vorhanden ?
1138     if( !GoInCntnt( rPam, fnMoveForward ) )
1139     {
1140         rPos = aSavePos;        // Cusror nicht veraendern
1141         return sal_False;
1142     }
1143     (rNds.*fnMove->fnSection)( &rPos.nNode );
1144     SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
1145     rPos.nContent.Assign( pNd,
1146                         ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
1147     return sal_True;
1148 }
1149 
1150 
GoPrevSection(SwPaM & rPam,SwMoveFn fnMove)1151 sal_Bool GoPrevSection( SwPaM & rPam, SwMoveFn fnMove )
1152 {
1153     SwPosition& rPos = *rPam.GetPoint();
1154     SwPosition aSavePos( rPos );        // eine Vergleichsposition
1155     SwNodes& rNds = aSavePos.nNode.GetNodes();
1156     rNds.GoStartOfSection( &rPos.nNode );
1157 
1158     // kein weiterer ContentNode vorhanden ?
1159     if( !GoInCntnt( rPam, fnMoveBackward ))
1160     {
1161         rPos = aSavePos;        // Cusror nicht veraendern
1162         return sal_False;
1163     }
1164     (rNds.*fnMove->fnSection)( &rPos.nNode );
1165     SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
1166     rPos.nContent.Assign( pNd,
1167                             ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ));
1168     return sal_True;
1169 }
1170 
1171 // #111827#
GetTxt() const1172 String SwPaM::GetTxt() const
1173 {
1174     String aResult;
1175 
1176     SwNodeIndex aNodeIndex = Start()->nNode;
1177 
1178     /* The first node can be the end node. A first end node must be
1179        handled, too. There fore do ... while and no incrementing of
1180        aNodeIndex in the first pass.
1181      */
1182     bool bFirst = true;
1183     do
1184     {
1185         if (! bFirst)
1186         {
1187             aNodeIndex++;
1188         }
1189 
1190         bFirst = false;
1191 
1192         SwTxtNode * pTxtNode = aNodeIndex.GetNode().GetTxtNode();
1193 
1194         if (pTxtNode != NULL)
1195         {
1196             const String & aTmpStr = pTxtNode->GetTxt();
1197 
1198             if (aNodeIndex == Start()->nNode)
1199             {
1200                 xub_StrLen nEnd;
1201                 if (End()->nNode == aNodeIndex)
1202                     nEnd = End()->nContent.GetIndex();
1203                 else
1204                     nEnd = aTmpStr.Len();
1205 
1206                 aResult += aTmpStr.Copy(Start()->nContent.GetIndex(),
1207                                         nEnd - Start()->nContent.GetIndex()) ;
1208             }
1209             else if (aNodeIndex == End()->nNode)
1210                 aResult += aTmpStr.Copy(0, End()->nContent.GetIndex());
1211             else
1212                 aResult += aTmpStr;
1213         }
1214     }
1215     while (aNodeIndex != End()->nNode);
1216 
1217     return aResult;
1218 }
1219 
Overlap(const SwPaM & a,const SwPaM & b)1220 sal_Bool SwPaM::Overlap(const SwPaM & a, const SwPaM & b)
1221 {
1222     return !(*b.End() <= *a.Start() || *a.End() <= *b.End());
1223 }
1224 
InvalidatePaM()1225 void SwPaM::InvalidatePaM()
1226 {
1227     const SwNode *_pNd=this->GetNode();
1228     const SwTxtNode *_pTxtNd=(_pNd!=NULL?_pNd->GetTxtNode():NULL);
1229     if (_pTxtNd!=NULL)
1230     {
1231         // pretent that the PaM marks inserted text to recalc the portion...
1232         SwInsTxt aHint( Start()->nContent.GetIndex(),
1233                         End()->nContent.GetIndex() - Start()->nContent.GetIndex() + 1 );
1234         SwModify *_pModify=(SwModify*)_pTxtNd;
1235         _pModify->ModifyNotification( 0, &aHint);
1236     }
1237 }
1238 
LessThan(const SwPaM & a,const SwPaM & b)1239 sal_Bool SwPaM::LessThan(const SwPaM & a, const SwPaM & b)
1240 {
1241     return (*a.Start() < *b.Start()) || (*a.Start() == *b.Start() && *a.End() < *b.End());
1242 }
1243