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