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