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