clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pam.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/core/crsr/pam.cxx
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | #include <sal/config.h> |
21 | |
22 | #include <string_view> |
23 | |
24 | #include <tools/gen.hxx> |
25 | #include <editeng/protitem.hxx> |
26 | #include <cntfrm.hxx> |
27 | #include <pagefrm.hxx> |
28 | #include <doc.hxx> |
29 | #include <IDocumentLayoutAccess.hxx> |
30 | #include <docary.hxx> |
31 | #include <pam.hxx> |
32 | #include <pamtyp.hxx> |
33 | #include <txtfrm.hxx> |
34 | #include <fmtcntnt.hxx> |
35 | #include <frmatr.hxx> |
36 | #include <flyfrm.hxx> |
37 | #include <fmteiro.hxx> |
38 | #include <section.hxx> |
39 | #include <sectfrm.hxx> |
40 | #include <ndtxt.hxx> |
41 | #include <swcrsr.hxx> |
42 | |
43 | #include <IMark.hxx> |
44 | #include <DocumentSettingManager.hxx> |
45 | #include <hints.hxx> |
46 | #include <txatbase.hxx> |
47 | #include <xmloff/odffields.hxx> |
48 | #include <rtl/ustrbuf.hxx> |
49 | |
50 | #include <editsh.hxx> |
51 | |
52 | |
53 | static sal_Int32 GetSttOrEnd( bool bCondition, const SwContentNode& rNd ) |
54 | { |
55 | return bCondition ? 0 : rNd.Len(); |
56 | } |
57 | |
58 | SwPosition::SwPosition( const SwNodeIndex & rNodeIndex, const SwIndex & rContent ) |
59 | : nNode( rNodeIndex ), nContent( rContent ) |
60 | { |
61 | } |
62 | |
63 | SwPosition::SwPosition( const SwNodeIndex & rNodeIndex ) |
64 | : nNode( rNodeIndex ), nContent( nNode.GetNode().GetContentNode() ) |
65 | { |
66 | } |
67 | |
68 | SwPosition::SwPosition( const SwNode& rNode ) |
69 | : nNode( rNode ), nContent( nNode.GetNode().GetContentNode() ) |
70 | { |
71 | } |
72 | |
73 | SwPosition::SwPosition( SwContentNode & rNode, const sal_Int32 nOffset ) |
74 | : nNode( rNode ), nContent( &rNode, nOffset ) |
75 | { |
76 | } |
77 | |
78 | bool SwPosition::operator<(const SwPosition &rPos) const |
79 | { |
80 | if( nNode < rPos.nNode ) |
81 | return true; |
82 | if( nNode == rPos.nNode ) |
83 | { |
84 | |
85 | |
86 | SwIndexReg const*const pThisReg(nContent.GetIdxReg()); |
87 | SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg()); |
88 | if (pThisReg && pOtherReg) |
89 | { |
90 | return (nContent < rPos.nContent); |
91 | } |
92 | else |
93 | { |
94 | return pOtherReg != nullptr; |
95 | } |
96 | } |
97 | return false; |
98 | } |
99 | |
100 | bool SwPosition::operator>(const SwPosition &rPos) const |
101 | { |
102 | if(nNode > rPos.nNode ) |
103 | return true; |
104 | if( nNode == rPos.nNode ) |
105 | { |
106 | |
107 | |
108 | SwIndexReg const*const pThisReg(nContent.GetIdxReg()); |
109 | SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg()); |
110 | if (pThisReg && pOtherReg) |
111 | { |
112 | return (nContent > rPos.nContent); |
113 | } |
114 | else |
115 | { |
116 | return pThisReg != nullptr; |
117 | } |
118 | } |
119 | return false; |
120 | } |
121 | |
122 | bool SwPosition::operator<=(const SwPosition &rPos) const |
123 | { |
124 | if(nNode < rPos.nNode ) |
125 | return true; |
126 | if( nNode == rPos.nNode ) |
127 | { |
128 | |
129 | |
130 | SwIndexReg const*const pThisReg(nContent.GetIdxReg()); |
131 | SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg()); |
132 | if (pThisReg && pOtherReg) |
133 | { |
134 | return (nContent <= rPos.nContent); |
135 | } |
136 | else |
137 | { |
138 | return pThisReg == nullptr; |
139 | } |
140 | } |
141 | return false; |
142 | } |
143 | |
144 | bool SwPosition::operator>=(const SwPosition &rPos) const |
145 | { |
146 | if(nNode > rPos.nNode ) |
147 | return true; |
148 | if( nNode == rPos.nNode ) |
149 | { |
150 | |
151 | |
152 | SwIndexReg const*const pThisReg(nContent.GetIdxReg()); |
153 | SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg()); |
154 | if (pThisReg && pOtherReg) |
155 | { |
156 | return (nContent >= rPos.nContent); |
157 | } |
158 | else |
159 | { |
160 | return pOtherReg == nullptr; |
161 | } |
162 | } |
163 | return false; |
164 | } |
165 | |
166 | bool SwPosition::operator==(const SwPosition &rPos) const |
167 | { |
168 | return (nNode == rPos.nNode) |
169 | && (nContent == rPos.nContent); |
170 | } |
171 | |
172 | bool SwPosition::operator!=(const SwPosition &rPos) const |
173 | { |
174 | return (nNode != rPos.nNode) |
175 | || (nContent != rPos.nContent); |
176 | } |
177 | |
178 | SwDoc& SwPosition::GetDoc() const |
179 | { |
180 | return nNode.GetNode().GetDoc(); |
181 | } |
182 | |
183 | void SwPosition::dumpAsXml(xmlTextWriterPtr pWriter) const |
184 | { |
185 | xmlTextWriterStartElement(pWriter, BAD_CAST("SwPosition")); |
186 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nNode"), BAD_CAST(OString::number(nNode.GetIndex()).getStr())); |
187 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nContent"), BAD_CAST(OString::number(nContent.GetIndex()).getStr())); |
188 | xmlTextWriterEndElement(pWriter); |
189 | } |
190 | |
191 | std::ostream &operator <<(std::ostream& s, const SwPosition& position) |
192 | { |
193 | return s << "SwPosition (node " << position.nNode.GetIndex() << ", offset " << position.nContent.GetIndex() << ")"; |
194 | } |
195 | |
196 | namespace { |
197 | |
198 | enum CHKSECTION { Chk_Both, Chk_One, Chk_None }; |
199 | |
200 | } |
201 | |
202 | static CHKSECTION lcl_TstIdx( sal_uLong nSttIdx, sal_uLong nEndIdx, const SwNode& rEndNd ) |
203 | { |
204 | sal_uLong nStt = rEndNd.StartOfSectionIndex(), nEnd = rEndNd.GetIndex(); |
205 | CHKSECTION eSec = nStt < nSttIdx && nEnd >= nSttIdx ? Chk_One : Chk_None; |
206 | if( nStt < nEndIdx && nEnd >= nEndIdx ) |
207 | return( eSec == Chk_One ? Chk_Both : Chk_One ); |
208 | return eSec; |
209 | } |
210 | |
211 | static bool lcl_ChkOneRange( CHKSECTION eSec, bool bChkSections, |
212 | const SwNode& rBaseEnd, sal_uLong nStt, sal_uLong nEnd ) |
213 | { |
214 | if( eSec != Chk_Both ) |
215 | return false; |
216 | |
217 | if( !bChkSections ) |
218 | return true; |
219 | |
220 | |
221 | const SwNodes& rNds = rBaseEnd.GetNodes(); |
222 | const SwNode *pTmp, *pNd = rNds[ nStt ]; |
223 | if( !pNd->IsStartNode() ) |
224 | pNd = pNd->StartOfSectionNode(); |
225 | |
226 | if( pNd == rNds[ nEnd ]->StartOfSectionNode() ) |
227 | return true; |
228 | |
229 | |
230 | if( !pNd->StartOfSectionIndex() ) |
231 | return false; |
232 | |
233 | for (;;) |
234 | { |
235 | pTmp = pNd->StartOfSectionNode(); |
236 | if (pTmp->EndOfSectionNode() == &rBaseEnd ) |
237 | break; |
238 | pNd = pTmp; |
239 | } |
240 | |
241 | sal_uLong nSttIdx = pNd->GetIndex(), nEndIdx = pNd->EndOfSectionIndex(); |
242 | return nSttIdx <= nStt && nStt <= nEndIdx && |
243 | nSttIdx <= nEnd && nEnd <= nEndIdx; |
244 | } |
245 | |
246 | |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | |
254 | |
255 | |
256 | bool CheckNodesRange( const SwNodeIndex& rStt, |
257 | const SwNodeIndex& rEnd, bool bChkSection ) |
258 | { |
259 | const SwNodes& rNds = rStt.GetNodes(); |
260 | sal_uLong nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex(); |
261 | CHKSECTION eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfContent() ); |
262 | if( Chk_None != eSec ) |
263 | return eSec == Chk_Both; |
264 | |
265 | eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfAutotext() ); |
266 | if( Chk_None != eSec ) |
267 | return lcl_ChkOneRange( eSec, bChkSection, |
268 | rNds.GetEndOfAutotext(), nStt, nEnd ); |
269 | |
270 | eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfPostIts() ); |
271 | if( Chk_None != eSec ) |
272 | return lcl_ChkOneRange( eSec, bChkSection, |
273 | rNds.GetEndOfPostIts(), nStt, nEnd ); |
274 | |
275 | eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfInserts() ); |
276 | if( Chk_None != eSec ) |
277 | return lcl_ChkOneRange( eSec, bChkSection, |
278 | rNds.GetEndOfInserts(), nStt, nEnd ); |
279 | |
280 | eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfRedlines() ); |
281 | if( Chk_None != eSec ) |
282 | return lcl_ChkOneRange( eSec, bChkSection, |
283 | rNds.GetEndOfRedlines(), nStt, nEnd ); |
284 | |
285 | return false; |
286 | } |
287 | |
288 | bool GoNext(SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode ) |
289 | { |
290 | if( pNd->IsContentNode() ) |
291 | return static_cast<SwContentNode*>(pNd)->GoNext( pIdx, nMode ); |
292 | return false; |
293 | } |
294 | |
295 | bool GoPrevious( SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode ) |
296 | { |
297 | if( pNd->IsContentNode() ) |
298 | return static_cast<SwContentNode*>(pNd)->GoPrevious( pIdx, nMode ); |
299 | return false; |
300 | } |
301 | |
302 | SwContentNode* GoNextNds( SwNodeIndex* pIdx, bool bChk ) |
303 | { |
304 | SwNodeIndex aIdx( *pIdx ); |
305 | SwContentNode* pNd = aIdx.GetNodes().GoNext( &aIdx ); |
306 | if( pNd ) |
307 | { |
308 | if( bChk && 1 != aIdx.GetIndex() - pIdx->GetIndex() && |
309 | !CheckNodesRange( *pIdx, aIdx, true ) ) |
310 | pNd = nullptr; |
311 | else |
312 | *pIdx = aIdx; |
313 | } |
314 | return pNd; |
315 | } |
316 | |
317 | SwContentNode* GoPreviousNds( SwNodeIndex * pIdx, bool bChk ) |
318 | { |
319 | SwNodeIndex aIdx( *pIdx ); |
320 | SwContentNode* pNd = SwNodes::GoPrevious( &aIdx ); |
321 | if( pNd ) |
322 | { |
323 | if( bChk && 1 != pIdx->GetIndex() - aIdx.GetIndex() && |
324 | !CheckNodesRange( *pIdx, aIdx, true ) ) |
325 | pNd = nullptr; |
326 | else |
327 | *pIdx = aIdx; |
328 | } |
329 | return pNd; |
330 | } |
331 | |
332 | SwPaM::SwPaM( const SwPosition& rPos, SwPaM* pRing ) |
333 | : Ring( pRing ) |
334 | , m_Bound1( rPos ) |
335 | , m_Bound2( rPos.nNode.GetNode().GetNodes() ) |
336 | , m_pPoint( &m_Bound1 ) |
337 | , m_pMark( m_pPoint ) |
338 | , m_bIsInFrontOfLabel( false ) |
339 | { |
340 | } |
341 | |
342 | SwPaM::SwPaM( const SwPosition& rMark, const SwPosition& rPoint, SwPaM* pRing ) |
343 | : Ring( pRing ) |
344 | , m_Bound1( rMark ) |
345 | , m_Bound2( rPoint ) |
346 | , m_pPoint( &m_Bound2 ) |
347 | , m_pMark( &m_Bound1 ) |
348 | , m_bIsInFrontOfLabel( false ) |
349 | { |
350 | } |
351 | |
352 | SwPaM::SwPaM( const SwNodeIndex& rMark, const SwNodeIndex& rPoint, |
353 | long nMarkOffset, long nPointOffset, SwPaM* pRing ) |
354 | : Ring( pRing ) |
355 | , m_Bound1( rMark ) |
356 | , m_Bound2( rPoint ) |
357 | , m_pPoint( &m_Bound2 ) |
358 | , m_pMark( &m_Bound1 ) |
359 | , m_bIsInFrontOfLabel( false ) |
360 | { |
361 | if ( nMarkOffset ) |
362 | { |
363 | m_pMark->nNode += nMarkOffset; |
364 | } |
365 | if ( nPointOffset ) |
366 | { |
367 | m_pPoint->nNode += nPointOffset; |
368 | } |
369 | m_Bound1.nContent.Assign( m_Bound1.nNode.GetNode().GetContentNode(), 0 ); |
370 | m_Bound2.nContent.Assign( m_Bound2.nNode.GetNode().GetContentNode(), 0 ); |
371 | } |
372 | |
373 | SwPaM::SwPaM( const SwNode& rMark, const SwNode& rPoint, |
374 | long nMarkOffset, long nPointOffset, SwPaM* pRing ) |
375 | : Ring( pRing ) |
376 | , m_Bound1( rMark ) |
377 | , m_Bound2( rPoint ) |
378 | , m_pPoint( &m_Bound2 ) |
379 | , m_pMark( &m_Bound1 ) |
380 | , m_bIsInFrontOfLabel( false ) |
381 | { |
382 | if ( nMarkOffset ) |
383 | { |
384 | m_pMark->nNode += nMarkOffset; |
385 | } |
386 | if ( nPointOffset ) |
387 | { |
388 | m_pPoint->nNode += nPointOffset; |
389 | } |
390 | m_Bound1.nContent.Assign( m_Bound1.nNode.GetNode().GetContentNode(), 0 ); |
391 | m_Bound2.nContent.Assign( m_Bound2.nNode.GetNode().GetContentNode(), 0 ); |
392 | } |
393 | |
394 | SwPaM::SwPaM( const SwNodeIndex& rMark, sal_Int32 nMarkContent, |
395 | const SwNodeIndex& rPoint, sal_Int32 nPointContent, SwPaM* pRing ) |
396 | : Ring( pRing ) |
397 | , m_Bound1( rMark ) |
398 | , m_Bound2( rPoint ) |
399 | , m_pPoint( &m_Bound2 ) |
400 | , m_pMark( &m_Bound1 ) |
401 | , m_bIsInFrontOfLabel( false ) |
402 | { |
403 | m_pPoint->nContent.Assign( rPoint.GetNode().GetContentNode(), nPointContent); |
404 | m_pMark ->nContent.Assign( rMark .GetNode().GetContentNode(), nMarkContent ); |
405 | } |
406 | |
407 | SwPaM::SwPaM( const SwNode& rMark, sal_Int32 nMarkContent, |
408 | const SwNode& rPoint, sal_Int32 nPointContent, SwPaM* pRing ) |
409 | : Ring( pRing ) |
410 | , m_Bound1( rMark ) |
411 | , m_Bound2( rPoint ) |
412 | , m_pPoint( &m_Bound2 ) |
413 | , m_pMark( &m_Bound1 ) |
414 | , m_bIsInFrontOfLabel( false ) |
415 | { |
416 | m_pPoint->nContent.Assign( m_pPoint->nNode.GetNode().GetContentNode(), |
417 | nPointContent); |
418 | m_pMark ->nContent.Assign( m_pMark ->nNode.GetNode().GetContentNode(), |
419 | nMarkContent ); |
420 | } |
421 | |
422 | SwPaM::SwPaM( const SwNode& rNode, sal_Int32 nContent, SwPaM* pRing ) |
423 | : Ring( pRing ) |
424 | , m_Bound1( rNode ) |
425 | , m_Bound2( m_Bound1.nNode.GetNode().GetNodes() ) |
426 | , m_pPoint( &m_Bound1 ) |
427 | , m_pMark( &m_Bound1 ) |
428 | , m_bIsInFrontOfLabel( false ) |
429 | { |
430 | m_pPoint->nContent.Assign( m_pPoint->nNode.GetNode().GetContentNode(), |
431 | nContent ); |
432 | } |
433 | |
434 | SwPaM::SwPaM( const SwNodeIndex& rNodeIdx, sal_Int32 nContent, SwPaM* pRing ) |
435 | : Ring( pRing ) |
436 | , m_Bound1( rNodeIdx ) |
437 | , m_Bound2( rNodeIdx.GetNode().GetNodes() ) |
438 | , m_pPoint( &m_Bound1 ) |
439 | , m_pMark( &m_Bound1 ) |
440 | , m_bIsInFrontOfLabel( false ) |
441 | { |
442 | m_pPoint->nContent.Assign( rNodeIdx.GetNode().GetContentNode(), nContent ); |
443 | } |
444 | |
445 | SwPaM::~SwPaM() {} |
446 | |
447 | SwPaM::SwPaM(SwPaM const& rPam, SwPaM *const pRing) |
448 | : Ring(pRing) |
449 | , m_Bound1( *(rPam.m_pPoint) ) |
450 | , m_Bound2( *(rPam.m_pMark) ) |
451 | , m_pPoint( &m_Bound1 ), m_pMark( rPam.HasMark() ? &m_Bound2 : m_pPoint ) |
452 | , m_bIsInFrontOfLabel( false ) |
453 | { |
454 | } |
455 | |
456 | |
457 | SwPaM &SwPaM::operator=( const SwPaM &rPam ) |
458 | { |
459 | if(this == &rPam) |
460 | return *this; |
461 | |
462 | *m_pPoint = *( rPam.m_pPoint ); |
463 | if ( rPam.HasMark() ) |
464 | { |
465 | SetMark(); |
466 | *m_pMark = *( rPam.m_pMark ); |
467 | } |
468 | else |
469 | { |
470 | DeleteMark(); |
471 | } |
472 | return *this; |
473 | } |
474 | |
475 | void SwPaM::SetMark() |
476 | { |
477 | if (m_pPoint == &m_Bound1) |
478 | { |
479 | m_pMark = &m_Bound2; |
480 | } |
481 | else |
482 | { |
483 | m_pMark = &m_Bound1; |
484 | } |
485 | (*m_pMark) = *m_pPoint; |
486 | } |
487 | |
488 | #ifdef DBG_UTIL |
489 | void SwPaM::Exchange() |
490 | { |
491 | if (m_pPoint != m_pMark) |
492 | { |
493 | SwPosition *pTmp = m_pPoint; |
494 | m_pPoint = m_pMark; |
495 | m_pMark = pTmp; |
496 | } |
497 | } |
498 | #endif |
499 | |
500 | |
501 | bool SwPaM::Move( SwMoveFnCollection const & fnMove, SwGoInDoc fnGo ) |
502 | { |
503 | const bool bRet = (*fnGo)( *this, fnMove ); |
504 | |
505 | m_bIsInFrontOfLabel = false; |
506 | return bRet; |
507 | } |
508 | |
509 | namespace sw { |
510 | |
511 | |
512 | |
513 | |
514 | |
515 | |
516 | |
517 | |
518 | |
519 | |
520 | |
521 | std::unique_ptr<SwPaM> MakeRegion(SwMoveFnCollection const & fnMove, |
522 | const SwPaM & rOrigRg) |
523 | { |
524 | std::unique_ptr<SwPaM> pPam; |
525 | { |
526 | pPam.reset(new SwPaM(rOrigRg, const_cast<SwPaM*>(&rOrigRg))); |
527 | |
528 | |
529 | |
530 | if( (pPam->GetMark()->*fnMove.fnCmpOp)( *pPam->GetPoint() ) ) |
531 | pPam->Exchange(); |
532 | } |
533 | return pPam; |
534 | } |
535 | |
536 | } |
537 | |
538 | void SwPaM::Normalize(bool bPointFirst) |
539 | { |
540 | if (HasMark()) |
541 | if ( ( bPointFirst && *m_pPoint > *m_pMark) || |
542 | (!bPointFirst && *m_pPoint < *m_pMark) ) |
543 | { |
544 | Exchange(); |
545 | } |
546 | } |
547 | |
548 | |
549 | sal_uInt16 SwPaM::GetPageNum( bool bAtPoint, const Point* pLayPos ) |
550 | { |
551 | const SwContentFrame* pCFrame; |
552 | const SwPageFrame *pPg; |
553 | const SwContentNode *pNd ; |
554 | const SwPosition* pPos = bAtPoint ? m_pPoint : m_pMark; |
555 | |
556 | std::pair<Point, bool> tmp; |
557 | if (pLayPos) |
558 | { |
559 | tmp.first = *pLayPos; |
560 | tmp.second = false; |
561 | } |
562 | if( nullptr != ( pNd = pPos->nNode.GetNode().GetContentNode() ) && |
563 | nullptr != (pCFrame = pNd->getLayoutFrame(pNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), pPos, pLayPos ? &tmp : nullptr)) && |
564 | nullptr != ( pPg = pCFrame->FindPageFrame() )) |
565 | return pPg->GetPhyPageNum(); |
566 | return 0; |
567 | } |
568 | |
569 | |
570 | static const SwFrame* lcl_FindEditInReadonlyFrame( const SwFrame& rFrame ) |
571 | { |
572 | const SwFrame* pRet = nullptr; |
573 | |
574 | const SwFlyFrame* pFly; |
575 | const SwSectionFrame* pSectionFrame; |
576 | |
577 | if( rFrame.IsInFly() && |
578 | (pFly = rFrame.FindFlyFrame())->GetFormat()->GetEditInReadonly().GetValue() && |
579 | pFly->Lower() && |
580 | !pFly->Lower()->IsNoTextFrame() ) |
581 | { |
582 | pRet = pFly; |
583 | } |
584 | else if ( rFrame.IsInSct() && |
585 | nullptr != ( pSectionFrame = rFrame.FindSctFrame() )->GetSection() && |
586 | pSectionFrame->GetSection()->IsEditInReadonlyFlag() ) |
587 | { |
588 | pRet = pSectionFrame; |
589 | } |
590 | |
591 | return pRet; |
592 | } |
593 | |
594 | |
595 | bool SwPaM::HasReadonlySel( bool bFormView ) const |
596 | { |
597 | bool bRet = false; |
598 | |
599 | const SwContentNode* pNd = GetPoint()->nNode.GetNode().GetContentNode(); |
600 | const SwContentFrame *pFrame = nullptr; |
601 | if ( pNd != nullptr ) |
| |
602 | { |
603 | Point aTmpPt; |
604 | std::pair<Point, bool> const tmp(aTmpPt, false); |
605 | pFrame = pNd->getLayoutFrame( |
606 | pNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), |
607 | GetPoint(), &tmp); |
608 | } |
609 | |
610 | |
611 | const SwFrame* pPointEditInReadonlyFrame = nullptr; |
612 | if ( pFrame != nullptr |
613 | && ( pFrame->IsProtected() |
614 | || ( bFormView |
615 | && nullptr == ( pPointEditInReadonlyFrame = lcl_FindEditInReadonlyFrame( *pFrame ) ) ) ) ) |
616 | { |
617 | bRet = true; |
618 | } |
619 | else if( pNd != nullptr ) |
| |
620 | { |
621 | const SwSectionNode* pSNd = pNd->GetSectionNode(); |
622 | if ( pSNd != nullptr |
623 | && ( pSNd->GetSection().IsProtectFlag() |
624 | || ( bFormView |
625 | && !pSNd->GetSection().IsEditInReadonlyFlag()) ) ) |
626 | { |
627 | bRet = true; |
628 | } |
629 | else |
630 | { |
631 | const SwSectionNode* pParentSectionNd = pNd->FindSectionNode(); |
632 | if ( pParentSectionNd != nullptr |
633 | && ( pParentSectionNd->GetSection().IsProtectFlag() |
634 | || ( bFormView && !pParentSectionNd->GetSection().IsEditInReadonlyFlag()) ) ) |
635 | { |
636 | bRet = true; |
637 | } |
638 | } |
639 | } |
640 | |
641 | if ( !bRet |
642 | && HasMark() |
643 | && GetPoint()->nNode != GetMark()->nNode ) |
644 | { |
645 | pNd = GetMark()->nNode.GetNode().GetContentNode(); |
646 | pFrame = nullptr; |
647 | if ( pNd != nullptr ) |
648 | { |
649 | Point aTmpPt; |
650 | std::pair<Point, bool> const tmp(aTmpPt, false); |
651 | pFrame = pNd->getLayoutFrame( |
652 | pNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), |
653 | GetMark(), &tmp); |
654 | } |
655 | |
656 | const SwFrame* pMarkEditInReadonlyFrame = nullptr; |
657 | if ( pFrame != nullptr |
658 | && ( pFrame->IsProtected() |
659 | || ( bFormView |
660 | && nullptr == ( pMarkEditInReadonlyFrame = lcl_FindEditInReadonlyFrame( *pFrame ) ) ) ) ) |
661 | { |
662 | bRet = true; |
663 | } |
664 | else if( pNd != nullptr ) |
665 | { |
666 | const SwSectionNode* pSNd = pNd->GetSectionNode(); |
667 | if ( pSNd != nullptr |
668 | && ( pSNd->GetSection().IsProtectFlag() |
669 | || ( bFormView |
670 | && !pSNd->GetSection().IsEditInReadonlyFlag()) ) ) |
671 | { |
672 | bRet = true; |
673 | } |
674 | } |
675 | |
676 | if ( !bRet && bFormView ) |
677 | { |
678 | |
679 | |
680 | if ( pPointEditInReadonlyFrame != pMarkEditInReadonlyFrame ) |
681 | bRet = true; |
682 | } |
683 | |
684 | |
685 | if( !bRet ) |
686 | { |
687 | sal_uLong nSttIdx = GetMark()->nNode.GetIndex(), |
688 | nEndIdx = GetPoint()->nNode.GetIndex(); |
689 | if( nEndIdx <= nSttIdx ) |
690 | { |
691 | sal_uLong nTmp = nSttIdx; |
692 | nSttIdx = nEndIdx; |
693 | nEndIdx = nTmp; |
694 | } |
695 | |
696 | |
697 | |
698 | |
699 | if( nSttIdx + 3 < nEndIdx ) |
700 | { |
701 | const SwSectionFormats& rFormats = GetDoc().GetSections(); |
702 | for( SwSectionFormats::size_type n = rFormats.size(); n; ) |
703 | { |
704 | const SwSectionFormat* pFormat = rFormats[ --n ]; |
705 | if( pFormat->GetProtect().IsContentProtected() ) |
706 | { |
707 | const SwFormatContent& rContent = pFormat->GetContent(false); |
708 | OSL_ENSURE( rContent.GetContentIdx(), "where is the SectionNode?" ); |
709 | sal_uLong nIdx = rContent.GetContentIdx()->GetIndex(); |
710 | if( nSttIdx <= nIdx && nEndIdx >= nIdx && |
711 | rContent.GetContentIdx()->GetNode().GetNodes().IsDocNodes() ) |
712 | { |
713 | bRet = true; |
714 | break; |
715 | } |
716 | } |
717 | } |
718 | } |
719 | } |
720 | } |
721 | |
722 | const SwDoc& rDoc = GetDoc(); |
723 | |
724 | const IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess(); |
725 | sw::mark::IFieldmark* pA = GetPoint() ? pMarksAccess->getFieldmarkFor( *GetPoint( ) ) : nullptr; |
| |
726 | sw::mark::IFieldmark* pB = GetMark() ? pMarksAccess->getFieldmarkFor( *GetMark( ) ) : pA; |
| 4 | | Assuming pointer value is null | |
|
| |
727 | |
728 | const bool bAtStartA = (pA != nullptr) && (pA->GetMarkStart() == *GetPoint()); |
| 6 | | Assuming the condition is false | |
|
729 | const bool bAtStartB = (pB != nullptr) && (pB->GetMarkStart() == *GetMark()); |
730 | |
731 | if (!bRet) |
| |
732 | { |
733 | bool bUnhandledMark = pA && pA->GetFieldname( ) == ODF_UNHANDLED; |
734 | |
735 | if ( ( pA == pB ) && bUnhandledMark ) |
| |
736 | bRet = true; |
737 | else |
738 | { |
739 | if ((pA == pB) && (bAtStartA != bAtStartB)) |
| |
740 | bRet = true; |
741 | else if (pA != pB) |
| |
742 | { |
743 | |
744 | |
745 | bRet = !( ( !pA || bAtStartA ) && ( !pB || bAtStartB ) ); |
746 | } |
747 | if( !bRet && rDoc.GetDocumentSettingManager().get( DocumentSettingId::PROTECT_FORM ) && (pA || pB) ) |
| 11 | | Assuming the condition is false | |
|
748 | { |
749 | |
750 | bRet = ( pA == nullptr ) || ( pB == nullptr ) || bAtStartA || bAtStartB; |
751 | } |
752 | } |
753 | } |
754 | else |
755 | { |
756 | |
757 | bRet = !( pA != nullptr && !bAtStartA && !bAtStartB && pA == pB ); |
758 | } |
759 | |
760 | if (!bRet) |
| |
761 | { |
762 | |
763 | if (rDoc.GetEditShell()) |
| 13 | | Assuming the condition is false | |
|
| |
764 | bRet = rDoc.GetEditShell()->IsCursorInParagraphMetadataField(); |
765 | } |
766 | |
767 | if (!bRet && |
| |
768 | rDoc.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS)) |
| 15 | | Assuming the condition is false | |
|
769 | { |
770 | if (rDoc.getIDocumentMarkAccess()->isBookmarkDeleted(*this)) |
771 | { |
772 | return true; |
773 | } |
774 | } |
775 | if (!bRet && |
| |
776 | rDoc.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_FIELDS)) |
| 17 | | Assuming the condition is true | |
|
777 | { |
778 | SwPosition const& rStart(*Start()); |
| |
779 | SwPosition const& rEnd(*End()); |
780 | for (SwNodeIndex n = rStart.nNode; n <= rEnd.nNode; ++n) |
781 | { |
782 | if (SwTextNode const*const pNode = n.GetNode().GetTextNode()) |
783 | { |
784 | if (SwpHints const*const pHints = pNode->GetpSwpHints()) |
785 | { |
786 | for (size_t i = 0; i < pHints->Count(); ++i) |
787 | { |
788 | SwTextAttr const*const pHint(pHints->Get(i)); |
789 | if (n == rStart.nNode && pHint->GetStart() < rStart.nContent.GetIndex()) |
790 | { |
791 | continue; |
792 | } |
793 | if (n == rEnd.nNode && rEnd.nContent.GetIndex() <= pHint->GetStart()) |
794 | { |
795 | break; |
796 | } |
797 | if (pHint->Which() == RES_TXTATR_FIELD |
798 | |
799 | && pHint->GetFormatField().GetField()->GetTyp()->Which() != SwFieldIds::JumpEdit) |
800 | { |
801 | return true; |
802 | } |
803 | } |
804 | } |
805 | } |
806 | } |
807 | } |
808 | |
809 | return bRet; |
810 | } |
811 | |
812 | |
813 | |
814 | |
815 | |
816 | SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, SwMoveFnCollection const & fnMove, |
817 | bool const bInReadOnly, SwRootFrame const*const i_pLayout) |
818 | { |
819 | SwRootFrame const*const pLayout(i_pLayout ? i_pLayout : |
820 | rPam.GetDoc().getIDocumentLayoutAccess().GetCurrentLayout()); |
821 | SwContentNode * pNd = nullptr; |
822 | if( ((*rPam.GetPoint()).*fnMove.fnCmpOp)( *rPam.GetMark() ) || |
823 | ( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) ) |
824 | { |
825 | if( rbFirst ) |
826 | { |
827 | rbFirst = false; |
828 | pNd = rPam.GetContentNode(); |
829 | if( pNd ) |
830 | { |
831 | SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout)); |
832 | if( |
833 | ( |
834 | nullptr == pFrame || |
835 | ( !bInReadOnly && pFrame->IsProtected() ) || |
836 | (pFrame->IsTextFrame() && static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow()) |
837 | ) || |
838 | ( !bInReadOnly && pNd->FindSectionNode() && |
839 | pNd->FindSectionNode()->GetSection().IsProtect() |
840 | ) |
841 | ) |
842 | { |
843 | pNd = nullptr; |
844 | } |
845 | } |
846 | } |
847 | |
848 | if( !pNd ) |
849 | { |
850 | SwPosition aPos( *rPam.GetPoint() ); |
851 | bool bSrchForward = &fnMove == &fnMoveForward; |
852 | SwNodes& rNodes = aPos.nNode.GetNodes(); |
853 | |
854 | |
855 | while( true ) |
856 | { |
857 | if (i_pLayout && aPos.nNode.GetNode().IsTextNode()) |
858 | { |
859 | auto const fal(sw::GetFirstAndLastNode(*pLayout, aPos.nNode)); |
860 | aPos.nNode = bSrchForward ? *fal.second : *fal.first; |
861 | } |
862 | |
863 | pNd = bSrchForward |
864 | ? rNodes.GoNextSection( &aPos.nNode, true, !bInReadOnly ) |
865 | : SwNodes::GoPrevSection( &aPos.nNode, true, !bInReadOnly ); |
866 | if( pNd ) |
867 | { |
868 | aPos.nContent.Assign( pNd, ::GetSttOrEnd( bSrchForward,*pNd )); |
869 | |
870 | if( (aPos.*fnMove.fnCmpOp)( *rPam.GetMark() ) ) |
871 | { |
872 | |
873 | SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout)); |
874 | if (nullptr == pFrame || |
875 | ( !bInReadOnly && pFrame->IsProtected() ) || |
876 | ( pFrame->IsTextFrame() && |
877 | static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow())) |
878 | { |
879 | pNd = nullptr; |
880 | continue; |
881 | } |
882 | *rPam.GetPoint() = aPos; |
883 | } |
884 | else |
885 | pNd = nullptr; |
886 | break; |
887 | } |
888 | break; |
889 | } |
890 | } |
891 | } |
892 | return pNd; |
893 | } |
894 | |
895 | void GoStartDoc( SwPosition * pPos ) |
896 | { |
897 | SwNodes& rNodes = pPos->nNode.GetNodes(); |
898 | pPos->nNode = *rNodes.GetEndOfContent().StartOfSectionNode(); |
899 | |
900 | SwContentNode* pCNd = rNodes.GoNext( &pPos->nNode ); |
901 | if( pCNd ) |
902 | pCNd->MakeStartIndex( &pPos->nContent ); |
903 | } |
904 | |
905 | void GoEndDoc( SwPosition * pPos ) |
906 | { |
907 | SwNodes& rNodes = pPos->nNode.GetNodes(); |
908 | pPos->nNode = rNodes.GetEndOfContent(); |
909 | SwContentNode* pCNd = GoPreviousNds( &pPos->nNode, true ); |
910 | if( pCNd ) |
911 | pCNd->MakeEndIndex( &pPos->nContent ); |
912 | } |
913 | |
914 | void GoStartSection( SwPosition * pPos ) |
915 | { |
916 | |
917 | SwNodes& rNodes = pPos->nNode.GetNodes(); |
918 | sal_uInt16 nLevel = SwNodes::GetSectionLevel( pPos->nNode ); |
919 | if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() ) |
920 | nLevel--; |
921 | do { SwNodes::GoStartOfSection( &pPos->nNode ); } while( nLevel-- ); |
922 | |
923 | |
924 | pPos->nNode.GetNode().GetContentNode()->MakeStartIndex( &pPos->nContent ); |
925 | } |
926 | |
927 | |
928 | void GoEndSection( SwPosition * pPos ) |
929 | { |
930 | |
931 | SwNodes& rNodes = pPos->nNode.GetNodes(); |
932 | sal_uInt16 nLevel = SwNodes::GetSectionLevel( pPos->nNode ); |
933 | if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() ) |
934 | nLevel--; |
935 | do { SwNodes::GoEndOfSection( &pPos->nNode ); } while( nLevel-- ); |
936 | |
937 | |
938 | if( GoPreviousNds( &pPos->nNode, true ) ) |
939 | pPos->nNode.GetNode().GetContentNode()->MakeEndIndex( &pPos->nContent ); |
940 | } |
941 | |
942 | bool GoInDoc( SwPaM & rPam, SwMoveFnCollection const & fnMove ) |
943 | { |
944 | (*fnMove.fnDoc)( rPam.GetPoint() ); |
945 | return true; |
946 | } |
947 | |
948 | bool GoInSection( SwPaM & rPam, SwMoveFnCollection const & fnMove ) |
949 | { |
950 | (*fnMove.fnSections)( rPam.GetPoint() ); |
951 | return true; |
952 | } |
953 | |
954 | bool GoInNode( SwPaM & rPam, SwMoveFnCollection const & fnMove ) |
955 | { |
956 | SwContentNode *pNd = (*fnMove.fnNds)( &rPam.GetPoint()->nNode, true ); |
957 | if( pNd ) |
958 | rPam.GetPoint()->nContent.Assign( pNd, |
959 | ::GetSttOrEnd( &fnMove == &fnMoveForward, *pNd ) ); |
960 | return pNd; |
961 | } |
962 | |
963 | bool GoInContent( SwPaM & rPam, SwMoveFnCollection const & fnMove ) |
964 | { |
965 | if( (*fnMove.fnNd)( &rPam.GetPoint()->nNode.GetNode(), |
966 | &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS )) |
967 | return true; |
968 | return GoInNode( rPam, fnMove ); |
969 | } |
970 | |
971 | bool GoInContentCells( SwPaM & rPam, SwMoveFnCollection const & fnMove ) |
972 | { |
973 | if( (*fnMove.fnNd)( &rPam.GetPoint()->nNode.GetNode(), |
974 | &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS )) |
975 | return true; |
976 | return GoInNode( rPam, fnMove ); |
977 | } |
978 | |
979 | bool GoInContentSkipHidden( SwPaM & rPam, SwMoveFnCollection const & fnMove ) |
980 | { |
981 | if( (*fnMove.fnNd)( &rPam.GetPoint()->nNode.GetNode(), |
982 | &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS | CRSR_SKIP_HIDDEN ) ) |
983 | return true; |
984 | return GoInNode( rPam, fnMove ); |
985 | } |
986 | |
987 | bool GoInContentCellsSkipHidden( SwPaM & rPam, SwMoveFnCollection const & fnMove ) |
988 | { |
989 | if( (*fnMove.fnNd)( &rPam.GetPoint()->nNode.GetNode(), |
990 | &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS | CRSR_SKIP_HIDDEN ) ) |
991 | return true; |
992 | return GoInNode( rPam, fnMove ); |
993 | } |
994 | |
995 | bool GoPrevPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara ) |
996 | { |
997 | if( rPam.Move( fnMoveBackward, GoInNode ) ) |
998 | { |
999 | |
1000 | SwPosition& rPos = *rPam.GetPoint(); |
1001 | SwContentNode * pNd = rPos.nNode.GetNode().GetContentNode(); |
1002 | rPos.nContent.Assign( pNd, |
1003 | ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ) ); |
1004 | return true; |
1005 | } |
1006 | return false; |
1007 | } |
1008 | |
1009 | bool GoCurrPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara ) |
1010 | { |
1011 | SwPosition& rPos = *rPam.GetPoint(); |
1012 | SwContentNode * pNd = rPos.nNode.GetNode().GetContentNode(); |
1013 | if( pNd ) |
1014 | { |
1015 | const sal_Int32 nOld = rPos.nContent.GetIndex(); |
1016 | const sal_Int32 nNew = &aPosPara == &fnMoveForward ? 0 : pNd->Len(); |
1017 | |
1018 | if( nOld != nNew ) |
1019 | { |
1020 | rPos.nContent.Assign( pNd, nNew ); |
1021 | return true; |
1022 | } |
1023 | } |
1024 | |
1025 | if( ( &aPosPara==&fnParaStart && nullptr != ( pNd = |
1026 | GoPreviousNds( &rPos.nNode, true ))) || |
1027 | ( &aPosPara==&fnParaEnd && nullptr != ( pNd = |
1028 | GoNextNds( &rPos.nNode, true ))) ) |
1029 | { |
1030 | rPos.nContent.Assign( pNd, |
1031 | ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd )); |
1032 | return true; |
1033 | } |
1034 | return false; |
1035 | } |
1036 | |
1037 | bool GoNextPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara ) |
1038 | { |
1039 | if( rPam.Move( fnMoveForward, GoInNode ) ) |
1040 | { |
1041 | |
1042 | SwPosition& rPos = *rPam.GetPoint(); |
1043 | SwContentNode * pNd = rPos.nNode.GetNode().GetContentNode(); |
1044 | rPos.nContent.Assign( pNd, |
1045 | ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ) ); |
1046 | return true; |
1047 | } |
1048 | return false; |
1049 | } |
1050 | |
1051 | bool GoCurrSection( SwPaM & rPam, SwMoveFnCollection const & fnMove ) |
1052 | { |
1053 | SwPosition& rPos = *rPam.GetPoint(); |
1054 | SwPosition aSavePos( rPos ); |
1055 | (fnMove.fnSection)( &rPos.nNode ); |
1056 | SwContentNode *pNd; |
1057 | if( nullptr == ( pNd = rPos.nNode.GetNode().GetContentNode()) && |
1058 | nullptr == ( pNd = (*fnMove.fnNds)( &rPos.nNode, true )) ) |
1059 | { |
1060 | rPos = aSavePos; |
1061 | return false; |
1062 | } |
1063 | |
1064 | rPos.nContent.Assign( pNd, |
1065 | ::GetSttOrEnd( &fnMove == &fnMoveForward, *pNd ) ); |
1066 | return aSavePos != rPos; |
1067 | } |
1068 | |
1069 | OUString SwPaM::GetText() const |
1070 | { |
1071 | OUStringBuffer aResult; |
1072 | |
1073 | SwNodeIndex aNodeIndex = Start()->nNode; |
1074 | |
1075 | |
1076 | |
1077 | |
1078 | bool bIsStartNode = true; |
1079 | for (;;) |
1080 | { |
1081 | const bool bIsEndNode = aNodeIndex == End()->nNode; |
1082 | SwTextNode * pTextNode = aNodeIndex.GetNode().GetTextNode(); |
1083 | |
1084 | if (pTextNode != nullptr) |
1085 | { |
1086 | if (!bIsStartNode) |
1087 | { |
1088 | aResult.append(CH_TXTATR_NEWLINE); |
1089 | } |
1090 | const OUString& aTmpStr = pTextNode->GetText(); |
1091 | |
1092 | if (bIsStartNode || bIsEndNode) |
1093 | { |
1094 | |
1095 | const sal_Int32 nStart = bIsStartNode |
1096 | ? Start()->nContent.GetIndex() |
1097 | : 0; |
1098 | const sal_Int32 nEnd = bIsEndNode |
1099 | ? End()->nContent.GetIndex() |
1100 | : aTmpStr.getLength(); |
1101 | |
1102 | aResult.append(std::u16string_view(aTmpStr).substr(nStart, nEnd-nStart)); |
1103 | } |
1104 | else |
1105 | { |
1106 | aResult.append(aTmpStr); |
1107 | } |
1108 | } |
1109 | |
1110 | if (bIsEndNode) |
1111 | { |
1112 | break; |
1113 | } |
1114 | |
1115 | ++aNodeIndex; |
1116 | bIsStartNode = false; |
1117 | } |
1118 | |
1119 | return aResult.makeStringAndClear(); |
1120 | } |
1121 | |
1122 | void SwPaM::InvalidatePaM() |
1123 | { |
1124 | const SwNode &_pNd = GetNode(); |
1125 | const SwTextNode *_pTextNd = _pNd.GetTextNode(); |
1126 | if (_pTextNd != nullptr) |
1127 | { |
1128 | |
1129 | SwInsText aHint( Start()->nContent.GetIndex(), |
1130 | End()->nContent.GetIndex() - Start()->nContent.GetIndex() + 1 ); |
1131 | SwModify *_pModify=const_cast<SwModify*>(static_cast<SwModify const *>(_pTextNd)); |
1132 | _pModify->ModifyNotification( nullptr, &aHint); |
1133 | } |
1134 | } |
1135 | |
1136 | void SwPaM::dumpAsXml(xmlTextWriterPtr pWriter) const |
1137 | { |
1138 | xmlTextWriterStartElement(pWriter, BAD_CAST("SwPaM")); |
1139 | |
1140 | xmlTextWriterStartElement(pWriter, BAD_CAST("point")); |
1141 | GetPoint()->dumpAsXml(pWriter); |
1142 | xmlTextWriterEndElement(pWriter); |
1143 | |
1144 | if (HasMark()) |
1145 | { |
1146 | xmlTextWriterStartElement(pWriter, BAD_CAST("mark")); |
1147 | GetMark()->dumpAsXml(pWriter); |
1148 | xmlTextWriterEndElement(pWriter); |
1149 | } |
1150 | |
1151 | xmlTextWriterEndElement(pWriter); |
1152 | } |
1153 | |
1154 | std::ostream &operator <<(std::ostream& s, const SwPaM& pam) |
1155 | { |
1156 | if( pam.HasMark()) |
1157 | return s << "SwPaM (point " << *pam.GetPoint() << ", mark " << *pam.GetMark() << ")"; |
1158 | else |
1159 | return s << "SwPaM (point " << *pam.GetPoint() << ")"; |
1160 | } |
1161 | |
1162 | |
1163 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | #ifndef INCLUDED_SW_INC_PAM_HXX |
20 | #define INCLUDED_SW_INC_PAM_HXX |
21 | |
22 | #include <sal/types.h> |
23 | #include "ring.hxx" |
24 | #include "index.hxx" |
25 | #include "ndindex.hxx" |
26 | #include "swdllapi.h" |
27 | |
28 | #include <iostream> |
29 | |
30 | class SwDoc; |
31 | class SwPaM; |
32 | class Point; |
33 | |
34 | |
35 | struct SAL_WARN_UNUSED SW_DLLPUBLIC SwPosition |
36 | { |
37 | SwNodeIndex nNode; |
38 | SwIndex nContent; |
39 | |
40 | SwPosition( const SwNodeIndex &rNode, const SwIndex &rContent ); |
41 | explicit SwPosition( const SwNodeIndex &rNode ); |
42 | explicit SwPosition( const SwNode& rNode ); |
43 | explicit SwPosition( SwContentNode& rNode, const sal_Int32 nOffset = 0 ); |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | SwDoc& GetDoc() const; |
51 | |
52 | bool operator < (const SwPosition &) const; |
53 | bool operator > (const SwPosition &) const; |
54 | bool operator <=(const SwPosition &) const; |
55 | bool operator >=(const SwPosition &) const; |
56 | bool operator ==(const SwPosition &) const; |
57 | bool operator !=(const SwPosition &) const; |
58 | void dumpAsXml(xmlTextWriterPtr pWriter) const; |
59 | }; |
60 | |
61 | SW_DLLPUBLIC std::ostream &operator <<(std::ostream& s, const SwPosition& position); |
62 | |
63 | |
64 | enum class SwComparePosition { |
65 | Before, |
66 | Behind, |
67 | Inside, |
68 | Outside, |
69 | Equal, |
70 | OverlapBefore, |
71 | OverlapBehind, |
72 | CollideStart, |
73 | CollideEnd |
74 | }; |
75 | |
76 | template<typename T> |
77 | SwComparePosition ComparePosition( |
78 | const T& rStt1, const T& rEnd1, |
79 | const T& rStt2, const T& rEnd2 ) |
80 | { |
81 | SwComparePosition nRet; |
82 | if( rStt1 < rStt2 ) |
83 | { |
84 | if( rEnd1 > rStt2 ) |
85 | { |
86 | if( rEnd1 >= rEnd2 ) |
87 | nRet = SwComparePosition::Outside; |
88 | else |
89 | nRet = SwComparePosition::OverlapBefore; |
90 | |
91 | } |
92 | else if( rEnd1 == rStt2 ) |
93 | nRet = SwComparePosition::CollideEnd; |
94 | else |
95 | nRet = SwComparePosition::Before; |
96 | } |
97 | else if( rEnd2 > rStt1 ) |
98 | { |
99 | if( rEnd2 >= rEnd1 ) |
100 | { |
101 | if( rEnd2 == rEnd1 && rStt2 == rStt1 ) |
102 | nRet = SwComparePosition::Equal; |
103 | else |
104 | nRet = SwComparePosition::Inside; |
105 | } |
106 | else |
107 | { |
108 | if (rStt1 == rStt2) |
109 | nRet = SwComparePosition::Outside; |
110 | else |
111 | nRet = SwComparePosition::OverlapBehind; |
112 | } |
113 | } |
114 | else if( rEnd2 == rStt1 ) |
115 | nRet = SwComparePosition::CollideStart; |
116 | else |
117 | nRet = SwComparePosition::Behind; |
118 | return nRet; |
119 | } |
120 | |
121 | |
122 | struct SwMoveFnCollection; |
123 | SW_DLLPUBLIC extern SwMoveFnCollection const & fnMoveForward; |
124 | SW_DLLPUBLIC extern SwMoveFnCollection const & fnMoveBackward; |
125 | |
126 | using SwGoInDoc = auto (*)(SwPaM& rPam, SwMoveFnCollection const & fnMove) -> bool; |
127 | SW_DLLPUBLIC bool GoInDoc( SwPaM&, SwMoveFnCollection const &); |
128 | bool GoInSection( SwPaM&, SwMoveFnCollection const &); |
129 | SW_DLLPUBLIC bool GoInNode( SwPaM&, SwMoveFnCollection const &); |
130 | SW_DLLPUBLIC bool GoInContent( SwPaM&, SwMoveFnCollection const &); |
131 | bool GoInContentCells( SwPaM&, SwMoveFnCollection const &); |
132 | bool GoInContentSkipHidden( SwPaM&, SwMoveFnCollection const &); |
133 | bool GoInContentCellsSkipHidden( SwPaM&, SwMoveFnCollection const &); |
134 | |
135 | |
136 | class SAL_WARN_UNUSED SW_DLLPUBLIC SwPaM : public sw::Ring<SwPaM> |
137 | { |
138 | SwPosition m_Bound1; |
139 | SwPosition m_Bound2; |
140 | SwPosition * m_pPoint; |
141 | SwPosition * m_pMark; |
142 | bool m_bIsInFrontOfLabel; |
143 | |
144 | SwPaM(SwPaM const& rPaM) = delete; |
145 | |
146 | public: |
147 | explicit SwPaM( const SwPosition& rPos, SwPaM* pRing = nullptr ); |
148 | SwPaM( const SwPosition& rMk, const SwPosition& rPt, SwPaM* pRing = nullptr ); |
149 | SwPaM( const SwNodeIndex& rMk, const SwNodeIndex& rPt, |
150 | long nMkOffset = 0, long nPtOffset = 0, SwPaM* pRing = nullptr ); |
151 | SwPaM( const SwNode& rMk, const SwNode& rPt, |
152 | long nMkOffset = 0, long nPtOffset = 0, SwPaM* pRing = nullptr ); |
153 | SwPaM( const SwNodeIndex& rMk, sal_Int32 nMkContent, |
154 | const SwNodeIndex& rPt, sal_Int32 nPtContent, SwPaM* pRing = nullptr ); |
155 | SwPaM( const SwNode& rMk, sal_Int32 nMkContent, |
156 | const SwNode& rPt, sal_Int32 nPtContent, SwPaM* pRing = nullptr ); |
157 | SwPaM( const SwNode& rNd, sal_Int32 nContent = 0, SwPaM* pRing = nullptr ); |
158 | SwPaM( const SwNodeIndex& rNd, sal_Int32 nContent = 0, SwPaM* pRing = nullptr ); |
159 | virtual ~SwPaM() override; |
160 | |
161 | |
162 | |
163 | SwPaM(SwPaM const& rPaM, SwPaM * pRing); |
164 | |
165 | SwPaM& operator=( const SwPaM & ); |
166 | |
167 | |
168 | bool Move( SwMoveFnCollection const & fnMove = fnMoveForward, |
169 | SwGoInDoc fnGo = GoInContent ); |
170 | |
171 | bool IsInFrontOfLabel() const { return m_bIsInFrontOfLabel; } |
172 | void SetInFrontOfLabel_( bool bNew ) { m_bIsInFrontOfLabel = bNew; } |
173 | |
174 | |
175 | virtual void SetMark(); |
176 | |
177 | void DeleteMark() |
178 | { |
179 | if (m_pMark != m_pPoint) |
180 | { |
181 | |
182 | |
183 | *m_pMark = SwPosition( SwNodeIndex( GetNode().GetNodes() ) ); |
184 | m_pMark = m_pPoint; |
185 | } |
186 | } |
187 | #ifdef DBG_UTIL |
188 | void Exchange(); |
189 | |
190 | #else |
191 | void Exchange() |
192 | { |
193 | if (m_pPoint != m_pMark) |
194 | { |
195 | SwPosition *pTmp = m_pPoint; |
196 | m_pPoint = m_pMark; |
197 | m_pMark = pTmp; |
198 | } |
199 | } |
200 | #endif |
201 | |
202 | |
203 | |
204 | |
205 | bool HasMark() const { return m_pPoint != m_pMark; } |
206 | |
207 | const SwPosition *GetPoint() const { return m_pPoint; } |
208 | SwPosition *GetPoint() { return m_pPoint; } |
209 | const SwPosition *GetMark() const { return m_pMark; } |
210 | SwPosition *GetMark() { return m_pMark; } |
211 | |
212 | const SwPosition *Start() const |
213 | { return (*m_pPoint) <= (*m_pMark) ? m_pPoint : m_pMark; } |
| 20 | | Forming reference to null pointer |
|
214 | SwPosition *Start() |
215 | { return (*m_pPoint) <= (*m_pMark) ? m_pPoint : m_pMark; } |
216 | |
217 | const SwPosition *End() const |
218 | { return (*m_pPoint) > (*m_pMark) ? m_pPoint : m_pMark; } |
219 | SwPosition *End() |
220 | { return (*m_pPoint) > (*m_pMark) ? m_pPoint : m_pMark; } |
221 | |
222 | |
223 | SwNode & GetNode ( bool bPoint = true ) const |
224 | { |
225 | return ( bPoint ? m_pPoint->nNode : m_pMark->nNode ).GetNode(); |
226 | } |
227 | |
228 | |
229 | SwContentNode* GetContentNode( bool bPoint = true ) const |
230 | { |
231 | return GetNode(bPoint).GetContentNode(); |
232 | } |
233 | |
234 | |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | void Normalize(bool bPointFirst = true); |
241 | |
242 | |
243 | SwDoc& GetDoc() const { return m_pPoint->nNode.GetNode().GetDoc(); } |
244 | |
245 | SwPosition& GetBound( bool bOne = true ) |
246 | { return bOne ? m_Bound1 : m_Bound2; } |
247 | const SwPosition& GetBound( bool bOne = true ) const |
248 | { return bOne ? m_Bound1 : m_Bound2; } |
249 | |
250 | |
251 | sal_uInt16 GetPageNum( bool bAtPoint = true, const Point* pLayPos = nullptr ); |
252 | |
253 | |
254 | |
255 | bool HasReadonlySel( bool bFormView ) const; |
256 | |
257 | bool ContainsPosition(const SwPosition & rPos) const |
258 | { |
259 | return *Start() <= rPos && rPos <= *End(); |
260 | } |
261 | |
262 | OUString GetText() const; |
263 | void InvalidatePaM(); |
264 | SwPaM* GetNext() |
265 | { return GetNextInRing(); } |
266 | const SwPaM* GetNext() const |
267 | { return GetNextInRing(); } |
268 | SwPaM* GetPrev() |
269 | { return GetPrevInRing(); } |
270 | const SwPaM* GetPrev() const |
271 | { return GetPrevInRing(); } |
272 | bool IsMultiSelection() const |
273 | { return !unique(); } |
274 | |
275 | void dumpAsXml(xmlTextWriterPtr pWriter) const; |
276 | }; |
277 | |
278 | SW_DLLPUBLIC std::ostream &operator <<(std::ostream& s, const SwPaM& pam); |
279 | |
280 | bool CheckNodesRange(const SwNodeIndex&, const SwNodeIndex&, bool bChkSection); |
281 | |
282 | #endif // INCLUDED_SW_INC_PAM_HXX |
283 | |
284 | |