LibreOffice Module sw (master) 1
acorrect.cxx
Go to the documentation of this file.
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 <hintids.hxx>
21
22#include <fmtinfmt.hxx>
23#include <editsh.hxx>
24#include <doc.hxx>
25#include <pam.hxx>
26#include <unocrsr.hxx>
27#include <txatbase.hxx>
28#include <txtfrm.hxx>
29#include <ndtxt.hxx>
30#include <acorrect.hxx>
31#include <shellio.hxx>
32#include <swundo.hxx>
33#include <viscrs.hxx>
34#include <com/sun/star/linguistic2/XHyphenator.hpp>
35#include <com/sun/star/linguistic2/XHyphenatedWord.hpp>
36#include <osl/diagnose.h>
37#include <svl/numformat.hxx>
38
39#include <editeng/acorrcfg.hxx>
41#include <rootfrm.hxx>
42
43using namespace ::com::sun::star;
44
45namespace {
46
47class PaMIntoCursorShellRing
48{
49 SwPaM &m_rDelPam, &m_rCursor;
50 SwPaM* m_pPrevDelPam;
51 SwPaM* m_pPrevCursor;
52
53 static void RemoveFromRing( SwPaM& rPam, SwPaM const * pPrev );
54public:
55 PaMIntoCursorShellRing( SwCursorShell& rSh, SwPaM& rCursor, SwPaM& rPam );
56 ~PaMIntoCursorShellRing();
57};
58
59}
60
61PaMIntoCursorShellRing::PaMIntoCursorShellRing(SwCursorShell& rCSh, SwPaM& rShCursor, SwPaM& rPam)
62 : m_rDelPam(rPam)
63 , m_rCursor(rShCursor)
64{
65 SwPaM* pShCursor = rCSh.GetCursor_();
66
67 m_pPrevDelPam = m_rDelPam.GetPrev();
68 m_pPrevCursor = m_rCursor.GetPrev();
69
70 m_rDelPam.GetRingContainer().merge(pShCursor->GetRingContainer());
71 m_rCursor.GetRingContainer().merge(pShCursor->GetRingContainer());
72}
73
74PaMIntoCursorShellRing::~PaMIntoCursorShellRing()
75{
76 // and take out the Pam again:
77 RemoveFromRing(m_rDelPam, m_pPrevDelPam);
78 RemoveFromRing(m_rCursor, m_pPrevCursor);
79}
80
81void PaMIntoCursorShellRing::RemoveFromRing( SwPaM& rPam, SwPaM const * pPrev )
82{
83 SwPaM* p;
84 SwPaM* pNext = &rPam;
85 do {
86 p = pNext;
87 pNext = p->GetNext();
88 p->MoveTo( &rPam );
89 } while( p != pPrev );
90}
91
93 sal_Unicode cIns )
94 : m_rEditSh( rEditShell ), m_rCursor( rPam )
95 , m_nEndUndoCounter(0)
96 , m_bUndoIdInitialized( cIns == 0 )
97{
98}
99
101{
102 for (int i = 0; i < m_nEndUndoCounter; ++i)
103 {
105 }
106}
107
109{
110 // this should work with plain SwPaM as well because start and end
111 // are always in same node, but since there is GetRanges already...
112 std::vector<std::shared_ptr<SwUnoCursor>> ranges;
113 if (sw::GetRanges(ranges, *m_rEditSh.GetDoc(), rDelPam))
114 {
115 DeleteSelImpl(rDelPam);
116 }
117 else
118 {
119 for (auto const& pCursor : ranges)
120 {
121 DeleteSelImpl(*pCursor);
122 }
123 }
124}
125
127{
128 SwDoc* pDoc = m_rEditSh.GetDoc();
129 if( pDoc->IsAutoFormatRedline() )
130 {
131 // so that also the DelPam be moved, include it in the
132 // Shell-Cursr-Ring !!
133 // ??? is that really necessary - this should never join nodes, so Update should be enough?
134// PaMIntoCursorShellRing aTmp( rEditSh, rCursor, rDelPam );
135 assert(rDelPam.GetPoint()->GetNode() == rDelPam.GetMark()->GetNode());
137 }
138 else
139 {
141 }
142}
143
144bool SwAutoCorrDoc::Delete( sal_Int32 nStt, sal_Int32 nEnd )
145{
146 SwTextNode const*const pTextNd = m_rCursor.GetPointNode().GetTextNode();
147 SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
148 pTextNd->getLayoutFrame(m_rEditSh.GetLayout())));
149 assert(pFrame);
150 SwPaM aSel(pFrame->MapViewToModelPos(TextFrameIndex(nStt)),
151 pFrame->MapViewToModelPos(TextFrameIndex(nEnd)));
152 DeleteSel( aSel );
153
156 return true;
157}
158
159bool SwAutoCorrDoc::Insert( sal_Int32 nPos, const OUString& rText )
160{
161 SwTextNode const*const pTextNd = m_rCursor.GetPointNode().GetTextNode();
162 SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
163 pTextNd->getLayoutFrame(m_rEditSh.GetLayout())));
164 assert(pFrame);
168 {
170 if( 1 == rText.getLength() )
171 {
174 }
175 }
176 return true;
177}
178
179bool SwAutoCorrDoc::Replace( sal_Int32 nPos, const OUString& rText )
180{
181 return ReplaceRange( nPos, rText.getLength(), rText );
182}
183
184bool SwAutoCorrDoc::ReplaceRange( sal_Int32 nPos, sal_Int32 nSourceLength, const OUString& rText )
185{
186 assert(nSourceLength == 1); // sw_redlinehide: this is currently the case,
187 // and ensures that the replace range cannot *contain* delete redlines,
188 // so we don't need something along the lines of:
189 // if (sw::GetRanges(ranges, *rEditSh.GetDoc(), aPam))
190 // ReplaceImpl(...)
191 // else
192 // ReplaceImpl(ranges.begin())
193 // for (ranges.begin() + 1; ranges.end(); )
194 // DeleteImpl(*it)
195
197 if ( !pNd )
198 {
199 return false;
200 }
201
202 SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
204 assert(pFrame);
205 std::pair<SwTextNode *, sal_Int32> const pos(pFrame->MapViewToModel(TextFrameIndex(nPos)));
206
207 SwPaM* pPam = &m_rCursor;
208 if (pPam->GetPoint()->GetNode() != *pos.first
209 || pPam->GetPoint()->GetContentIndex() != pos.second)
210 {
211 pPam = new SwPaM(*pos.first, pos.second);
212 }
213
214 // text attributes with dummy characters must not be replaced!
215 bool bDoReplace = true;
216 sal_Int32 const nLen = rText.getLength();
217 for (sal_Int32 n = 0; n < nLen && n + nPos < pFrame->GetText().getLength(); ++n)
218 {
219 sal_Unicode const Char = pFrame->GetText()[n + nPos];
221 {
222 assert(pFrame->MapViewToModel(TextFrameIndex(n+nPos)).first->GetTextAttrForCharAt(pFrame->MapViewToModel(TextFrameIndex(n+nPos)).second));
223 bDoReplace = false;
224 break;
225 }
226 }
227
228 // tdf#83419 avoid bad autocorrect with visible redlines
229 // e.g. replacing the first letter of the tracked deletion
230 // with its capitalized (and not deleted) version.
231 if ( bDoReplace && !pFrame->getRootFrame()->IsHideRedlines() &&
232 m_rEditSh.GetDoc()->getIDocumentRedlineAccess().HasRedline( *pPam, RedlineType::Delete, /*bStartOrEndInRange=*/false ) )
233 {
234 bDoReplace = false;
235 }
236
237 if ( bDoReplace )
238 {
239 SwDoc* pDoc = m_rEditSh.GetDoc();
240
241 if( pDoc->IsAutoFormatRedline() )
242 {
243 if (nPos == pFrame->GetText().getLength()) // at the End do an Insert
244 {
245 pDoc->getIDocumentContentOperations().InsertString( *pPam, rText );
246 }
247 else
248 {
249 assert(pos.second != pos.first->Len()); // must be _before_ char
250 PaMIntoCursorShellRing aTmp( m_rEditSh, m_rCursor, *pPam );
251
252 pPam->SetMark();
253 pPam->GetPoint()->SetContent( std::min<sal_Int32>(
254 pos.first->GetText().getLength(), pos.second + nSourceLength) );
255 pDoc->getIDocumentContentOperations().ReplaceRange( *pPam, rText, false );
256 pPam->Exchange();
257 pPam->DeleteMark();
258 }
259 }
260 else
261 {
262 pPam->SetMark();
263 pPam->GetPoint()->SetContent( std::min<sal_Int32>(
264 pos.first->GetText().getLength(), pos.second + nSourceLength) );
265 pDoc->getIDocumentContentOperations().ReplaceRange( *pPam, rText, false );
266 pPam->Exchange();
267 pPam->DeleteMark();
268 }
269
271 {
273 if( 1 == rText.getLength() )
274 {
277 }
278 }
279 }
280
281 if( pPam != &m_rCursor )
282 delete pPam;
283
284 return true;
285}
286
287void SwAutoCorrDoc::SetAttr( sal_Int32 nStt, sal_Int32 nEnd, sal_uInt16 nSlotId,
288 SfxPoolItem& rItem )
289{
290 SwTextNode const*const pTextNd = m_rCursor.GetPointNode().GetTextNode();
291 SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
292 pTextNd->getLayoutFrame(m_rEditSh.GetLayout())));
293 assert(pFrame);
294 SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(nStt)),
295 pFrame->MapViewToModelPos(TextFrameIndex(nEnd)));
296
298 sal_uInt16 nWhich = rPool.GetWhich( nSlotId, false );
299 if( nWhich )
300 {
301 rItem.SetWhich( nWhich );
302
303 SfxItemSet aSet( rPool, aCharFormatSetRange );
304 SetAllScriptItem( aSet, rItem );
305
307
310 }
311}
312
313bool SwAutoCorrDoc::SetINetAttr( sal_Int32 nStt, sal_Int32 nEnd, const OUString& rURL )
314{
315 SwTextNode const*const pTextNd = m_rCursor.GetPointNode().GetTextNode();
316 SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
317 pTextNd->getLayoutFrame(m_rEditSh.GetLayout())));
318 assert(pFrame);
319 SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(nStt)),
320 pFrame->MapViewToModelPos(TextFrameIndex(nEnd)));
321
323 aSet( m_rEditSh.GetDoc()->GetAttrPool() );
324 aSet.Put( SwFormatINetFormat( rURL, OUString() ));
328 return true;
329}
330
337OUString const* SwAutoCorrDoc::GetPrevPara(bool const bAtNormalPos)
338{
339 OUString const* pStr(nullptr);
340
341 if( bAtNormalPos || !m_oIndex )
342 {
343 m_oIndex.emplace(m_rCursor.GetPoint()->GetNode());
344 }
346
347 SwTextFrame const* pFrame(nullptr);
348 for (SwTextNode * pTextNd = m_oIndex->GetNode().GetTextNode();
349 pTextNd; pTextNd = m_oIndex->GetNode().GetTextNode())
350 {
351 pFrame = static_cast<SwTextFrame const*>(
352 pTextNd->getLayoutFrame(m_rEditSh.GetLayout()));
353 if (pFrame && !pFrame->GetText().isEmpty())
354 {
355 break;
356 }
358 }
359 if (pFrame && !pFrame->GetText().isEmpty() &&
361 {
362 pStr = & pFrame->GetText();
363 }
364
367
368 return pStr;
369}
370
371bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos,
372 SvxAutoCorrect& rACorrect,
373 OUString* pPara )
374{
377
378 // Found a beginning of a paragraph or a Blank,
379 // search for the word Kuerzel (Shortcut) in the Auto
381 OSL_ENSURE( pTextNd, "where is the TextNode?" );
382
383 bool bRet = false;
384 if( nEndPos == rSttPos )
385 return bRet;
386
387 LanguageType eLang = GetLanguage(nEndPos);
388 if(LANGUAGE_SYSTEM == eLang)
389 eLang = GetAppLanguage();
390 LanguageTag aLanguageTag( eLang);
391
392 SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
393 pTextNd->getLayoutFrame(m_rEditSh.GetLayout())));
394 assert(pFrame);
395
396 const OUString sFrameText = pFrame->GetText();
397 const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList(
398 sFrameText, rSttPos, nEndPos, *this, aLanguageTag);
399 SwDoc* pDoc = m_rEditSh.GetDoc();
400 if( pFnd )
401 {
402 // replace also last colon of keywords surrounded by colons (for example, ":name:")
403 const bool replaceLastChar = sFrameText.getLength() > nEndPos && pFnd->GetShort()[0] == ':'
404 && pFnd->GetShort().endsWith(":");
405
406 SwPosition aStartPos( pFrame->MapViewToModelPos(TextFrameIndex(rSttPos) ));
407 SwPosition aEndPos( pFrame->MapViewToModelPos(TextFrameIndex(nEndPos + (replaceLastChar ? 1 : 0))) );
408 SwPaM aPam(aStartPos, aEndPos);
409
410 // don't replace, if a redline starts or ends within the original text
411 if ( pDoc->getIDocumentRedlineAccess().HasRedline( aPam, RedlineType::Any, /*bStartOrEndInRange=*/true ) )
412 {
413 return bRet;
414 }
415
416 if( pFnd->IsTextOnly() )
417 {
418 //JP 22.04.99: Bug 63883 - Special treatment for dots.
419 const bool bLastCharIsPoint
420 = nEndPos < sFrameText.getLength() && ('.' == sFrameText[nEndPos]);
421 if( !bLastCharIsPoint || pFnd->GetLong().isEmpty() ||
422 '.' != pFnd->GetLong()[ pFnd->GetLong().getLength() - 1 ] )
423 {
424 // replace the selection
425 std::vector<std::shared_ptr<SwUnoCursor>> ranges;
426 if (sw::GetRanges(ranges, *m_rEditSh.GetDoc(), aPam))
427 {
428 pDoc->getIDocumentContentOperations().ReplaceRange(aPam, pFnd->GetLong(), false);
429 bRet = true;
430 }
431 else if (!ranges.empty())
432 {
433 assert(ranges.front()->GetPoint()->GetNode() == ranges.front()->GetMark()->GetNode());
435 *ranges.front(), pFnd->GetLong(), false);
436 for (auto it = ranges.begin() + 1; it != ranges.end(); ++it)
437 {
438 DeleteSelImpl(**it);
439 }
440 bRet = true;
441 }
442
443 // tdf#83260 After calling sw::DocumentContentOperationsManager::ReplaceRange
444 // pTextNd may become invalid when change tracking is on and Edit -> Track Changes -> Show == OFF.
445 // ReplaceRange shows changes, this moves deleted nodes from special section to document.
446 // Then Show mode is disabled again. As a result pTextNd may be invalidated.
447 pTextNd = m_rCursor.GetPointNode().GetTextNode();
448 }
449 }
450 else
451 {
452 SwTextBlocks aTBlks( rACorrect.GetAutoCorrFileName( aLanguageTag, false, true ));
453 sal_uInt16 nPos = aTBlks.GetIndex( pFnd->GetShort() );
454 if( USHRT_MAX != nPos && aTBlks.BeginGetDoc( nPos ) )
455 {
456 DeleteSel( aPam );
457 pDoc->DontExpandFormat( *aPam.GetPoint() );
458
459 if( pPara )
460 {
461 OSL_ENSURE( !m_oIndex, "who has not deleted his Index?" );
462 m_oIndex.emplace(m_rCursor.GetPoint()->GetNode());
464 }
465
466 SwDoc* pAutoDoc = aTBlks.GetDoc();
467 SwNodeIndex aSttIdx( pAutoDoc->GetNodes().GetEndOfExtras(), 1 );
468 SwContentNode* pContentNd = pAutoDoc->GetNodes().GoNext( &aSttIdx );
469 SwPaM aCpyPam( aSttIdx );
470
471 const SwTableNode* pTableNd = pContentNd->FindTableNode();
472 if( pTableNd )
473 {
474 aCpyPam.GetPoint()->Assign( *pTableNd );
475 }
476 aCpyPam.SetMark();
477
478 // then until the end of the Nodes Array
479 aCpyPam.GetPoint()->Assign( pAutoDoc->GetNodes().GetEndOfContent(), SwNodeOffset(-1) );
480 pContentNd = aCpyPam.GetPointContentNode();
481 if (pContentNd)
482 aCpyPam.GetPoint()->SetContent( pContentNd->Len() );
483
484 SwDontExpandItem aExpItem;
485 aExpItem.SaveDontExpandItems( *aPam.GetPoint() );
486
488
489 aExpItem.RestoreDontExpandItems( *aPam.GetPoint() );
490
491 if( pPara )
492 {
494 pTextNd = m_oIndex->GetNode().GetTextNode();
495 }
496 bRet = true;
497 }
498 aTBlks.EndGetDoc();
499 }
500 }
501
502 if( bRet && pPara && pTextNd )
503 {
504 SwTextFrame const*const pNewFrame(static_cast<SwTextFrame const*>(
505 pTextNd->getLayoutFrame(m_rEditSh.GetLayout())));
506 *pPara = pNewFrame->GetText();
507 }
508
509 return bRet;
510}
511
512bool SwAutoCorrDoc::TransliterateRTLWord( sal_Int32& rSttPos, sal_Int32 nEndPos, bool bApply )
513{
516
518 OSL_ENSURE( pTextNd, "where is the TextNode?" );
519
520 bool bRet = false;
521 if( nEndPos == rSttPos )
522 return bRet;
523
524 LanguageType eLang = GetLanguage(nEndPos);
525 if(LANGUAGE_SYSTEM == eLang)
526 eLang = GetAppLanguage();
527 LanguageTag aLanguageTag(eLang);
528
529 SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
530 pTextNd->getLayoutFrame(m_rEditSh.GetLayout())));
531 assert(pFrame);
532
533 const OUString sFrameText = pFrame->GetText();
534 SwDoc* pDoc = m_rEditSh.GetDoc();
535 if ( pFrame->IsRightToLeft() || bApply )
536 {
537 // transliterate to Old Hungarian using Numbertext via NatNum12 number format modifier
538 OUString sWord(sFrameText.copy(rSttPos, nEndPos - rSttPos));
539 // Consonant disambiguation using hyphenation
540 uno::Reference< linguistic2::XHyphenator > xHyph;
541 xHyph = ::GetHyphenator();
542 OUStringBuffer sDisambiguatedWord;
543
544 const ::css::uno::Sequence< ::css::beans::PropertyValue > aProperties;
545 css::uno::Reference< css::linguistic2::XHyphenatedWord > xHyphWord;
546 for (int i = 0; i+1 < sWord.getLength(); i++ )
547 {
548 xHyphWord = xHyph->hyphenate( sWord,
549 aLanguageTag.getLocale(),
550 i,
551 aProperties );
552 // insert ZWSP at a hyphenation point, if it's not an alternative one (i.e. ssz->sz-sz)
553 if (xHyphWord.is() && xHyphWord->getHyphenationPos()+1 == i && !xHyphWord->isAlternativeSpelling())
554 {
555 sDisambiguatedWord.append(CHAR_ZWSP);
556 }
557 sDisambiguatedWord.append(sWord[i]);
558 }
559 sDisambiguatedWord.append(sWord[sWord.getLength()-1]);
560
561 SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter();
562 OUString sConverted;
563 if (pFormatter && !sWord.isEmpty())
564 {
565 const Color* pColor = nullptr;
566
567 // Send text as NatNum12 prefix: "word" -> "[NatNum12 word]0"
568
569 // Closing bracket doesn't allowed in NatNum parameters, remove it from transliteration:
570 // "[word]" -> "[NatNum12 [word]0"
571 bool bHasBracket = sWord.endsWith("]");
572 if ( !bHasBracket )
573 sDisambiguatedWord.append("]");
574 OUString sPrefix("[NatNum12 " + sDisambiguatedWord + "0");
575 if (pFormatter->GetPreviewString(sPrefix, 0, sConverted, &pColor, LANGUAGE_USER_HUNGARIAN_ROVAS))
576 {
577 if ( bHasBracket )
578 sConverted = sConverted + "]";
579 bRet = true;
580 }
581 }
582
583 SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(rSttPos)),
584 pFrame->MapViewToModelPos(TextFrameIndex(nEndPos)));
585 if (bRet && nEndPos <= sFrameText.getLength())
586 pDoc->getIDocumentContentOperations().ReplaceRange(aPam, sConverted, false);
587 }
588
589 return bRet;
590}
591
592// Called by the functions:
593// - FnCapitalStartWord
594// - FnCapitalStartSentence
595// after the exchange of characters. Then the words, if necessary, can be inserted
596// into the exception list.
597void SwAutoCorrDoc::SaveCpltSttWord( ACFlags nFlag, sal_Int32 nPos,
598 const OUString& rExceptWord,
599 sal_Unicode cChar )
600{
601 SwNodeOffset nNode = m_oIndex ? m_oIndex->GetIndex() : m_rCursor.GetPoint()->GetNodeIndex();
603 m_rEditSh.GetDoc()->SetAutoCorrExceptWord( std::make_unique<SwAutoCorrExceptWord>( nFlag,
604 nNode, nPos, rExceptWord, cChar, eLang ));
605}
606
608{
610
612
613 if( pNd )
614 {
615 SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
617 assert(pFrame);
618 eRet = pFrame->GetLangOfChar(TextFrameIndex(nPos), 0, true);
619 }
620 if(LANGUAGE_SYSTEM == eRet)
621 eRet = GetAppLanguage();
622 return eRet;
623}
624
626{
627 // test only if this is an improvement.
628 // If yes, then add the word to the list.
629 if (m_cChar == cChr && rPos.GetNodeIndex() == m_nNode && rPos.GetContentIndex() == m_nContent)
630 {
631 // get the current autocorrection:
633
634 // then add to the list:
635 if (ACFlags::CapitalStartWord & m_nFlags)
637 else if (ACFlags::CapitalStartSentence & m_nFlags)
639 }
640}
641
643{
644 bool bRet = false;
645 if (!m_bDeleted && rPos.GetNodeIndex() == m_nNode && rPos.GetContentIndex() == m_nContent)
646 m_bDeleted = bRet = true;
647 return bRet;
648}
649
651{
652}
653
655{
656 const SwTextNode* pTextNd = rPos.GetNode().GetTextNode();
657 if( pTextNd )
658 {
659 m_pDontExpandItems.reset( new SfxItemSet( const_cast<SwDoc&>(pTextNd->GetDoc()).GetAttrPool(),
661 const sal_Int32 n = rPos.GetContentIndex();
662 if (!pTextNd->GetParaAttr( *m_pDontExpandItems, n, n,
663 n != pTextNd->GetText().getLength() ))
664 {
665 m_pDontExpandItems.reset();
666 }
667 }
668}
669
671{
672 SwTextNode* pTextNd = rPos.GetNode().GetTextNode();
673 if( !pTextNd )
674 return;
675
676 const sal_Int32 nStart = rPos.GetContentIndex();
677 if( nStart == pTextNd->GetText().getLength() )
678 pTextNd->FormatToTextAttr( pTextNd );
679
680 if( !(pTextNd->GetpSwpHints() && pTextNd->GetpSwpHints()->Count()) )
681 return;
682
683 const size_t nSize = pTextNd->GetpSwpHints()->Count();
684 sal_Int32 nAttrStart;
685
686 for( size_t n = 0; n < nSize; ++n )
687 {
688 SwTextAttr* pHt = pTextNd->GetpSwpHints()->Get( n );
689 nAttrStart = pHt->GetStart();
690 if( nAttrStart > nStart ) // beyond the area
691 break;
692
693 const sal_Int32* pAttrEnd;
694 if( nullptr != ( pAttrEnd = pHt->End() ) &&
695 ( ( nAttrStart < nStart &&
696 ( pHt->DontExpand() ? nStart < *pAttrEnd
697 : nStart <= *pAttrEnd )) ||
698 ( nStart == nAttrStart &&
699 ( nAttrStart == *pAttrEnd || !nStart ))) )
700 {
701 const SfxPoolItem* pItem;
702 if( !m_pDontExpandItems || SfxItemState::SET != m_pDontExpandItems->
703 GetItemState( pHt->Which(), false, &pItem ) ||
704 *pItem != pHt->GetAttr() )
705 {
706 // The attribute was not previously set in this form in the
707 // paragraph, so it can only be created through insert/copy
708 // Because of that it is a candidate for DontExpand
709 pHt->SetDontExpand( true );
710 }
711 }
712 }
713}
714
715/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ CheckPosInFly
check if target position is in fly anchored at source range
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
PropertiesInfo aProperties
virtual bool DeleteAndJoin(SwPaM &, SwDeleteFlags flags=SwDeleteFlags::Default)=0
complete delete of a given PaM
virtual bool CopyRange(SwPaM &rPam, SwPosition &rPos, SwCopyFlags flags) const =0
Copy a selected content range to a position.
virtual void DeleteRange(SwPaM &)=0
Delete a range SwFlyFrameFormat.
virtual bool ReplaceRange(SwPaM &rPam, const OUString &rNewStr, const bool bRegExReplace)=0
Replace selected range in a TextNode with string.
virtual bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND)=0
Insert string into existing text node at position rRg.Point().
virtual bool HasRedline(const SwPaM &rPam, RedlineType nType, bool bStartOrEndInRange) const =0
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void SetWhich(sal_uInt16 nId)
bool GetPreviewString(const OUString &sFormatString, double fPreviewNumber, OUString &sOutString, const Color **ppColor, LanguageType eLnge, bool bUseStarFormat=false)
SvxAutoCorrect * GetAutoCorrect()
static SvxAutoCorrCfg & Get()
bool AddWordStartException(const OUString &rNew, LanguageType eLang)
OUString GetAutoCorrFileName(const LanguageTag &rLanguageTag, bool bNewFile=false, bool bTstUserExist=false, bool bUnlocalized=false) const
bool AddCplSttException(const OUString &rNew, LanguageType eLang)
const SvxAutocorrWord * SearchWordsInList(std::u16string_view rTxt, sal_Int32 &rStt, sal_Int32 nEndPos, SvxAutoCorrDoc &rDoc, LanguageTag &rLang)
bool IsTextOnly() const
const OUString & GetShort() const
const OUString & GetLong() const
virtual LanguageType GetLanguage(sal_Int32 nPos) const override
Definition: acorrect.cxx:607
virtual bool ReplaceRange(sal_Int32 nPos, sal_Int32 nLen, const OUString &rText) override
Definition: acorrect.cxx:184
int m_nEndUndoCounter
Definition: acorrect.hxx:54
virtual bool Replace(sal_Int32 nPos, const OUString &rText) override
Definition: acorrect.cxx:179
virtual bool TransliterateRTLWord(sal_Int32 &rSttPos, sal_Int32 nEndPos, bool bApply=false) override
Definition: acorrect.cxx:512
virtual void SaveCpltSttWord(ACFlags nFlag, sal_Int32 nPos, const OUString &rExceptWord, sal_Unicode cChar) override
Definition: acorrect.cxx:597
void DeleteSel(SwPaM &rDelPam)
Definition: acorrect.cxx:108
virtual bool SetINetAttr(sal_Int32 nStt, sal_Int32 nEnd, const OUString &rURL) override
Definition: acorrect.cxx:313
virtual bool Delete(sal_Int32 nStt, sal_Int32 nEnd) override
Definition: acorrect.cxx:144
virtual void SetAttr(sal_Int32 nStt, sal_Int32 nEnd, sal_uInt16 nSlotId, SfxPoolItem &) override
Definition: acorrect.cxx:287
void DeleteSelImpl(SwPaM &rDelPam)
Definition: acorrect.cxx:126
virtual bool ChgAutoCorrWord(sal_Int32 &rSttPos, sal_Int32 nEndPos, SvxAutoCorrect &rACorrect, OUString *pPara) override
Definition: acorrect.cxx:371
virtual bool Insert(sal_Int32 nPos, const OUString &rText) override
Definition: acorrect.cxx:159
virtual ~SwAutoCorrDoc() override
Definition: acorrect.cxx:100
SwAutoCorrDoc(SwEditShell &rEditShell, SwPaM &rPam, sal_Unicode cIns=0)
Definition: acorrect.cxx:92
virtual OUString const * GetPrevPara(bool bAtNormalPos) override
Return the text of a previous paragraph.
Definition: acorrect.cxx:337
std::optional< SwNodeIndex > m_oIndex
Definition: acorrect.hxx:53
SwPaM & m_rCursor
Definition: acorrect.hxx:52
SwEditShell & m_rEditSh
Definition: acorrect.hxx:51
bool m_bUndoIdInitialized
Definition: acorrect.hxx:55
sal_Int32 m_nContent
Definition: acorrect.hxx:101
SwNodeOffset m_nNode
Definition: acorrect.hxx:99
LanguageType m_eLanguage
Definition: acorrect.hxx:103
sal_Unicode m_cChar
Definition: acorrect.hxx:102
bool CheckDelChar(const SwPosition &rPos)
Definition: acorrect.cxx:642
void CheckChar(const SwPosition &rPos, sal_Unicode cChar)
Definition: acorrect.cxx:625
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1223
virtual sal_Int32 Len() const
Definition: node.cxx:1256
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:343
Definition: doc.hxx:197
bool IsAutoFormatRedline() const
Definition: doc.hxx:1465
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:329
void SetAutoCorrExceptWord(std::unique_ptr< SwAutoCorrExceptWord > pNew)
Definition: docedt.cxx:816
SwNodes & GetNodes()
Definition: doc.hxx:422
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:349
bool DontExpandFormat(const SwPosition &rPos, bool bFlag=true)
Definition: docfmt.cxx:1722
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1337
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1429
void SetFormatItemByAutoFormat(const SwPaM &rPam, const SfxItemSet &)
Definition: docfmt.cxx:1839
void RestoreDontExpandItems(const SwPosition &rPos)
Definition: acorrect.cxx:670
std::unique_ptr< SfxItemSet > m_pDontExpandItems
Definition: acorrect.hxx:38
void SaveDontExpandItems(const SwPosition &rPos)
Definition: acorrect.cxx:654
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:223
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
bool IsRightToLeft() const
Definition: frame.hxx:993
SwRootFrame * getRootFrame()
Definition: frame.hxx:685
Marks a node in the document model.
Definition: ndindex.hxx:31
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
SwDoc & GetDoc()
Definition: node.hxx:233
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:380
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:163
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1299
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
const SwPosition * GetMark() const
Definition: pam.hxx:255
SwNode & GetPointNode() const
Definition: pam.hxx:275
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:643
void Exchange()
Definition: pam.hxx:242
SwContentNode * GetPointContentNode() const
Definition: pam.hxx:279
void DeleteMark()
Definition: pam.hxx:232
const SwPosition * GetPoint() const
Definition: pam.hxx:253
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding).
Definition: rootfrm.hxx:434
SwShellCursor * GetPrev()
Definition: viscrs.hxx:190
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:167
const sal_Int32 * End() const
Definition: txatbase.hxx:156
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
bool DontExpand() const
Definition: txatbase.hxx:98
void SetDontExpand(bool bDontExpand)
Definition: txatbase.hxx:179
sal_uInt16 Which() const
Definition: txatbase.hxx:116
SwDoc * GetDoc()
Definition: swblocks.cxx:481
bool BeginGetDoc(sal_uInt16)
Definition: swblocks.cxx:359
sal_uInt16 GetIndex(const OUString &) const
Definition: swblocks.cxx:261
void EndGetDoc()
Definition: swblocks.cxx:379
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1333
LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, bool bNoChar=false) const
Definition: txtfrm.cxx:1430
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1318
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1380
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1390
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
bool GetParaAttr(SfxItemSet &rSet, sal_Int32 nStt, sal_Int32 nEnd, const bool bOnlyTextAttr=false, const bool bGetFromChrFormat=true, const bool bMergeIndentValuesOfNumRule=false, SwRootFrame const *pLayout=nullptr) const
Query the attributes of textnode over the range.
Definition: thints.cxx:2140
void FormatToTextAttr(SwTextNode *pNd)
Convey attributes of an AttrSet (AutoFormat) to SwpHintsArray.
Definition: thints.cxx:2539
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4168
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:252
const OUString & GetText() const
Definition: ndtxt.hxx:244
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2163
SwDoc * GetDoc() const
Definition: viewsh.hxx:308
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
size_t Count() const
Definition: ndhints.hxx:142
void merge(RingContainer< value_type > aDestRing)
Merges two ring containers.
Definition: ring.hxx:182
ring_container GetRingContainer()
Definition: ring.hxx:240
#define CH_TXTATR_INWORD
Definition: hintids.hxx:175
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:174
WhichRangesContainer const aCharFormatSetRange(svl::Items< RES_CHRATR_BEGIN, RES_CHRATR_END-1, RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1 >)
LanguageType GetAppLanguage()
Definition: init.cxx:741
void * p
sal_Int64 n
#define LANGUAGE_SYSTEM
#define LANGUAGE_USER_HUNGARIAN_ROVAS
sal_uInt16 nPos
OUString sPrefix
double getLength(const B2DPolygon &rCandidate)
int i
constexpr OUStringLiteral first
void GotoNextLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1473
void GotoPrevLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1438
bool GetRanges(std::vector< std::shared_ptr< SwUnoCursor > > &rRanges, SwDoc &rDoc, SwPaM const &rDelPam)
Definition: autofmt.cxx:1111
void SetAllScriptItem(SfxItemSet &rSet, const SfxPoolItem &rItem)
Definition: poolfmt.cxx:41
Marks a position in the document model.
Definition: pam.hxx:38
SwNode & GetNode() const
Definition: pam.hxx:81
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:231
void SetContent(sal_Int32 nContentIndex)
Set content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:267
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:78
sal_Int32 GetContentIndex() const
Definition: pam.hxx:85
ACFlags
uno::Reference< linguistic2::XHyphenator > GetHyphenator()
Definition: swtypes.cxx:57
#define CHAR_ZWSP
Definition: swtypes.hxx:178
sal_uInt16 sal_Unicode
size_t pos