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 
43 using namespace ::com::sun::star;
44 
45 namespace {
46 
47 class 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 );
54 public:
55  PaMIntoCursorShellRing( SwCursorShell& rSh, SwPaM& rCursor, SwPaM& rPam );
56  ~PaMIntoCursorShellRing();
57 };
58 
59 }
60 
61 PaMIntoCursorShellRing::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 
74 PaMIntoCursorShellRing::~PaMIntoCursorShellRing()
75 {
76  // and take out the Pam again:
77  RemoveFromRing(m_rDelPam, m_pPrevDelPam);
78  RemoveFromRing(m_rCursor, m_pPrevCursor);
79 }
80 
81 void 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  {
104  m_rEditSh.EndUndo();
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()->nNode == rDelPam.GetMark()->nNode);
136  pDoc->getIDocumentContentOperations().DeleteAndJoin( rDelPam );
137  }
138  else
139  {
140  pDoc->getIDocumentContentOperations().DeleteRange( rDelPam );
141  }
142 }
143 
144 bool SwAutoCorrDoc::Delete( sal_Int32 nStt, sal_Int32 nEnd )
145 {
146  SwTextNode const*const pTextNd = m_rCursor.GetNode().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 
155  m_bUndoIdInitialized = true;
156  return true;
157 }
158 
159 bool SwAutoCorrDoc::Insert( sal_Int32 nPos, const OUString& rText )
160 {
161  SwTextNode const*const pTextNd = m_rCursor.GetNode().GetTextNode();
162  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
163  pTextNd->getLayoutFrame(m_rEditSh.GetLayout())));
164  assert(pFrame);
165  SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(nPos)));
167  if( !m_bUndoIdInitialized )
168  {
169  m_bUndoIdInitialized = true;
170  if( 1 == rText.getLength() )
171  {
174  }
175  }
176  return true;
177 }
178 
179 bool SwAutoCorrDoc::Replace( sal_Int32 nPos, const OUString& rText )
180 {
181  return ReplaceRange( nPos, rText.getLength(), rText );
182 }
183 
184 bool 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 
196  SwTextNode * const pNd = m_rCursor.GetNode().GetTextNode();
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()->nNode != *pos.first
209  || pPam->GetPoint()->nContent != 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];
220  if (CH_TXTATR_BREAKWORD == Char || CH_TXTATR_INWORD == Char)
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()->nContent = 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()->nContent = 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  {
272  m_bUndoIdInitialized = true;
273  if( 1 == rText.getLength() )
274  {
277  }
278  }
279  }
280 
281  if( pPam != &m_rCursor )
282  delete pPam;
283 
284  return true;
285 }
286 
287 void SwAutoCorrDoc::SetAttr( sal_Int32 nStt, sal_Int32 nEnd, sal_uInt16 nSlotId,
288  SfxPoolItem& rItem )
289 {
290  SwTextNode const*const pTextNd = m_rCursor.GetNode().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 
297  SfxItemPool& rPool = m_rEditSh.GetDoc()->GetAttrPool();
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 
306  m_rEditSh.GetDoc()->SetFormatItemByAutoFormat( aPam, aSet );
307 
309  m_bUndoIdInitialized = true;
310  }
311 }
312 
313 bool SwAutoCorrDoc::SetINetAttr( sal_Int32 nStt, sal_Int32 nEnd, const OUString& rURL )
314 {
315  SwTextNode const*const pTextNd = m_rCursor.GetNode().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() ));
325  m_rEditSh.GetDoc()->SetFormatItemByAutoFormat( aPam, aSet );
327  m_bUndoIdInitialized = true;
328  return true;
329 }
330 
337 OUString const* SwAutoCorrDoc::GetPrevPara(bool const bAtNormalPos)
338 {
339  OUString const* pStr(nullptr);
340 
341  if( bAtNormalPos || !m_pIndex )
342  {
344  }
346 
347  SwTextFrame const* pFrame(nullptr);
348  for (SwTextNode * pTextNd = m_pIndex->GetNode().GetTextNode();
349  pTextNd; pTextNd = m_pIndex->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() &&
360  0 == pFrame->GetTextNodeForParaProps()->GetAttrOutlineLevel())
361  {
362  pStr = & pFrame->GetText();
363  }
364 
366  m_bUndoIdInitialized = true;
367 
368  return pStr;
369 }
370 
371 bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos,
372  SvxAutoCorrect& rACorrect,
373  OUString* pPara )
374 {
376  m_bUndoIdInitialized = true;
377 
378  // Found a beginning of a paragraph or a Blank,
379  // search for the word Kuerzel (Shortcut) in the Auto
380  SwTextNode* pTextNd = m_rCursor.GetNode().GetTextNode();
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()->nNode == ranges.front()->GetMark()->nNode);
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.GetNode().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_pIndex, "who has not deleted his Index?" );
462  m_pIndex.reset(new SwNodeIndex( m_rCursor.GetPoint()->nNode ));
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()->nContent.Assign( nullptr, 0 );
475  aCpyPam.GetPoint()->nNode = *pTableNd;
476  }
477  aCpyPam.SetMark();
478 
479  // then until the end of the Nodes Array
480  aCpyPam.GetPoint()->nNode.Assign( pAutoDoc->GetNodes().GetEndOfContent(), -1 );
481  pContentNd = aCpyPam.GetContentNode();
482  aCpyPam.GetPoint()->nContent.Assign(
483  pContentNd, pContentNd ? pContentNd->Len() : 0);
484 
485  SwDontExpandItem aExpItem;
486  aExpItem.SaveDontExpandItems( *aPam.GetPoint() );
487 
489 
490  aExpItem.RestoreDontExpandItems( *aPam.GetPoint() );
491 
492  if( pPara )
493  {
495  pTextNd = m_pIndex->GetNode().GetTextNode();
496  }
497  bRet = true;
498  }
499  aTBlks.EndGetDoc();
500  }
501  }
502 
503  if( bRet && pPara && pTextNd )
504  {
505  SwTextFrame const*const pNewFrame(static_cast<SwTextFrame const*>(
506  pTextNd->getLayoutFrame(m_rEditSh.GetLayout())));
507  *pPara = pNewFrame->GetText();
508  }
509 
510  return bRet;
511 }
512 
513 bool SwAutoCorrDoc::TransliterateRTLWord( sal_Int32& rSttPos, sal_Int32 nEndPos, bool bApply )
514 {
516  m_bUndoIdInitialized = true;
517 
518  SwTextNode* pTextNd = m_rCursor.GetNode().GetTextNode();
519  OSL_ENSURE( pTextNd, "where is the TextNode?" );
520 
521  bool bRet = false;
522  if( nEndPos == rSttPos )
523  return bRet;
524 
525  LanguageType eLang = GetLanguage(nEndPos);
526  if(LANGUAGE_SYSTEM == eLang)
527  eLang = GetAppLanguage();
528  LanguageTag aLanguageTag(eLang);
529 
530  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
531  pTextNd->getLayoutFrame(m_rEditSh.GetLayout())));
532  assert(pFrame);
533 
534  const OUString sFrameText = pFrame->GetText();
535  SwDoc* pDoc = m_rEditSh.GetDoc();
536  if ( pFrame->IsRightToLeft() || bApply )
537  {
538  // transliterate to Old Hungarian using Numbertext via NatNum12 number format modifier
539  OUString sWord(sFrameText.copy(rSttPos, nEndPos - rSttPos));
540  // Consonant disambiguation using hyphenation
541  uno::Reference< linguistic2::XHyphenator > xHyph;
542  xHyph = ::GetHyphenator();
543  OUStringBuffer sDisambiguatedWord;
544 
545  const ::css::uno::Sequence< ::css::beans::PropertyValue > aProperties;
546  css::uno::Reference< css::linguistic2::XHyphenatedWord > xHyphWord;
547  for (int i = 0; i+1 < sWord.getLength(); i++ )
548  {
549  xHyphWord = xHyph->hyphenate( sWord,
550  aLanguageTag.getLocale(),
551  i,
552  aProperties );
553  // insert ZWSP at a hyphenation point, if it's not an alternative one (i.e. ssz->sz-sz)
554  if (xHyphWord.is() && xHyphWord->getHyphenationPos()+1 == i && !xHyphWord->isAlternativeSpelling())
555  {
556  sDisambiguatedWord.append(CHAR_ZWSP);
557  }
558  sDisambiguatedWord.append(sWord[i]);
559  }
560  sDisambiguatedWord.append(sWord[sWord.getLength()-1]);
561 
562  SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter();
563  OUString sConverted;
564  if (pFormatter && !sWord.isEmpty())
565  {
566  const Color* pColor = nullptr;
567  // Send text as NatNum12 prefix
568  OUString sPrefix("[NatNum12 " + sDisambiguatedWord.makeStringAndClear() + "]0");
569  if (pFormatter->GetPreviewString(sPrefix, 0, sConverted, &pColor, LANGUAGE_USER_HUNGARIAN_ROVAS))
570  bRet = true;
571  }
572 
573  SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(rSttPos)),
574  pFrame->MapViewToModelPos(TextFrameIndex(nEndPos)));
575  if (bRet && nEndPos <= sFrameText.getLength())
576  pDoc->getIDocumentContentOperations().ReplaceRange(aPam, sConverted, false);
577  }
578 
579  return bRet;
580 }
581 
582 // Called by the functions:
583 // - FnCapitalStartWord
584 // - FnCapitalStartSentence
585 // after the exchange of characters. Then the words, if necessary, can be inserted
586 // into the exception list.
587 void SwAutoCorrDoc::SaveCpltSttWord( ACFlags nFlag, sal_Int32 nPos,
588  const OUString& rExceptWord,
589  sal_Unicode cChar )
590 {
591  SwNodeOffset nNode = m_pIndex ? m_pIndex->GetIndex() : m_rCursor.GetPoint()->nNode.GetIndex();
592  LanguageType eLang = GetLanguage(nPos);
593  m_rEditSh.GetDoc()->SetAutoCorrExceptWord( std::make_unique<SwAutoCorrExceptWord>( nFlag,
594  nNode, nPos, rExceptWord, cChar, eLang ));
595 }
596 
598 {
600 
602 
603  if( pNd )
604  {
605  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
607  assert(pFrame);
608  eRet = pFrame->GetLangOfChar(TextFrameIndex(nPos), 0, true);
609  }
610  if(LANGUAGE_SYSTEM == eRet)
611  eRet = GetAppLanguage();
612  return eRet;
613 }
614 
616 {
617  // test only if this is an improvement.
618  // If yes, then add the word to the list.
619  if (m_cChar == cChr && rPos.nNode.GetIndex() == m_nNode && rPos.nContent.GetIndex() == m_nContent)
620  {
621  // get the current autocorrection:
623 
624  // then add to the list:
625  if (ACFlags::CapitalStartWord & m_nFlags)
627  else if (ACFlags::CapitalStartSentence & m_nFlags)
629  }
630 }
631 
633 {
634  bool bRet = false;
635  if (!m_bDeleted && rPos.nNode.GetIndex() == m_nNode && rPos.nContent.GetIndex() == m_nContent)
636  m_bDeleted = bRet = true;
637  return bRet;
638 }
639 
641 {
642 }
643 
645 {
646  const SwTextNode* pTextNd = rPos.nNode.GetNode().GetTextNode();
647  if( pTextNd )
648  {
649  m_pDontExpandItems.reset( new SfxItemSet( const_cast<SwDoc&>(pTextNd->GetDoc()).GetAttrPool(),
651  const sal_Int32 n = rPos.nContent.GetIndex();
652  if (!pTextNd->GetParaAttr( *m_pDontExpandItems, n, n,
653  n != pTextNd->GetText().getLength() ))
654  {
655  m_pDontExpandItems.reset();
656  }
657  }
658 }
659 
661 {
662  SwTextNode* pTextNd = rPos.nNode.GetNode().GetTextNode();
663  if( !pTextNd )
664  return;
665 
666  const sal_Int32 nStart = rPos.nContent.GetIndex();
667  if( nStart == pTextNd->GetText().getLength() )
668  pTextNd->FormatToTextAttr( pTextNd );
669 
670  if( !(pTextNd->GetpSwpHints() && pTextNd->GetpSwpHints()->Count()) )
671  return;
672 
673  const size_t nSize = pTextNd->GetpSwpHints()->Count();
674  sal_Int32 nAttrStart;
675 
676  for( size_t n = 0; n < nSize; ++n )
677  {
678  SwTextAttr* pHt = pTextNd->GetpSwpHints()->Get( n );
679  nAttrStart = pHt->GetStart();
680  if( nAttrStart > nStart ) // beyond the area
681  break;
682 
683  const sal_Int32* pAttrEnd;
684  if( nullptr != ( pAttrEnd = pHt->End() ) &&
685  ( ( nAttrStart < nStart &&
686  ( pHt->DontExpand() ? nStart < *pAttrEnd
687  : nStart <= *pAttrEnd )) ||
688  ( nStart == nAttrStart &&
689  ( nAttrStart == *pAttrEnd || !nStart ))) )
690  {
691  const SfxPoolItem* pItem;
692  if( !m_pDontExpandItems || SfxItemState::SET != m_pDontExpandItems->
693  GetItemState( pHt->Which(), false, &pItem ) ||
694  *pItem != pHt->GetAttr() )
695  {
696  // The attribute was not previously set in this form in the
697  // paragraph, so it can only be created through insert/copy
698  // Because of that it is a candidate for DontExpand
699  pHt->SetDontExpand( true );
700  }
701  }
702  }
703 }
704 
705 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool ReplaceRange(sal_Int32 nPos, sal_Int32 nLen, const OUString &rText) override
Definition: acorrect.cxx:184
void merge(RingContainer< value_type > aDestRing)
Merges two ring containers.
Definition: ring.hxx:182
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:159
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:224
void SetDontExpand(bool bDontExpand)
Definition: txatbase.hxx:179
static SvxAutoCorrCfg & Get()
bool GetRanges(std::vector< std::shared_ptr< SwUnoCursor >> &rRanges, SwDoc &rDoc, SwPaM const &rDelPam)
Definition: autofmt.cxx:1112
Marks a position in the document model.
Definition: pam.hxx:36
virtual bool HasRedline(const SwPaM &rPam, RedlineType nType, bool bStartOrEndInRange) const =0
const OUString & GetText() const
Definition: ndtxt.hxx:218
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:226
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1410
SwNodeIndex nNode
Definition: pam.hxx:38
virtual bool SetINetAttr(sal_Int32 nStt, sal_Int32 nEnd, const OUString &rURL) override
Definition: acorrect.cxx:313
const SwPosition * GetMark() const
Definition: pam.hxx:210
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1210
sal_Int64 n
Definition: doc.hxx:187
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:116
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1296
SwShellCursor * GetPrev()
Definition: viscrs.hxx:178
bool AddCplSttException(const OUString &rNew, LanguageType eLang)
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
const OUString & GetShort() const
virtual ~SwAutoCorrDoc() override
Definition: acorrect.cxx:100
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:587
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:230
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:173
void DeleteSel(SwPaM &rDelPam)
Definition: acorrect.cxx:108
sal_uInt16 sal_Unicode
#define CH_TXTATR_INWORD
Definition: hintids.hxx:174
LanguageType m_eLanguage
Definition: acorrect.hxx:102
ACFlags
PropertiesInfo aProperties
int m_nEndUndoCounter
Definition: acorrect.hxx:53
SwIndex nContent
Definition: pam.hxx:39
size_t pos
void RestoreDontExpandItems(const SwPosition &rPos)
Definition: acorrect.cxx:660
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:43
check if target position is in fly anchored at source range
void SetAllScriptItem(SfxItemSet &rSet, const SfxPoolItem &rItem)
Definition: poolfmt.cxx:41
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
void SetFormatItemByAutoFormat(const SwPaM &rPam, const SfxItemSet &)
Definition: docfmt.cxx:1820
void SaveDontExpandItems(const SwPosition &rPos)
Definition: acorrect.cxx:644
SwDoc * GetDoc() const
Definition: viewsh.hxx:282
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:152
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:265
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:162
SwEditShell & m_rEditSh
Definition: acorrect.hxx:50
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:333
virtual bool Insert(sal_Int32 nPos, const OUString &rText) override
Definition: acorrect.cxx:159
SwNodeOffset m_nNode
Definition: acorrect.hxx:98
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
virtual bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND)=0
Insert string into existing text node at position rRg.Point().
SwNodeIndex & Assign(SwNodes const &rNds, SwNodeOffset)
Definition: ndindex.hxx:272
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
SwDoc & GetDoc()
Definition: node.hxx:213
const SwPosition * GetPoint() const
Definition: pam.hxx:208
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:2103
WhichRangesContainer const aCharFormatSetRange(svl::Items< RES_CHRATR_BEGIN, RES_CHRATR_END-1, RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1 >)
SvxAutoCorrect * GetAutoCorrect()
void DeleteSelImpl(SwPaM &rDelPam)
Definition: acorrect.cxx:126
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:101
#define CHAR_ZWSP
Definition: swtypes.hxx:166
Marks a node in the document model.
Definition: ndindex.hxx:30
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:615
OUString sPrefix
bool AddWordStartException(const OUString &rNew, LanguageType eLang)
void SetAutoCorrExceptWord(std::unique_ptr< SwAutoCorrExceptWord > pNew)
Definition: docedt.cxx:826
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
virtual OUString const * GetPrevPara(bool bAtNormalPos) override
Return the text of a previous paragraph.
Definition: acorrect.cxx:337
virtual bool TransliterateRTLWord(sal_Int32 &rSttPos, sal_Int32 nEndPos, bool bApply=false) override
Definition: acorrect.cxx:513
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
virtual LanguageType GetLanguage(sal_Int32 nPos) const override
Definition: acorrect.cxx:597
sal_Int32 m_nContent
Definition: acorrect.hxx:100
bool CheckDelChar(const SwPosition &rPos)
Definition: acorrect.cxx:632
bool DontExpandFormat(const SwPosition &rPos, bool bFlag=true)
Definition: docfmt.cxx:1703
void SetWhich(sal_uInt16 nId)
sal_Int32 GetIndex() const
Definition: index.hxx:91
LanguageType GetAppLanguage()
Definition: init.cxx:725
SwNodes & GetNodes()
Definition: doc.hxx:408
const sal_Int32 * End() const
Definition: txatbase.hxx:156
virtual bool ChgAutoCorrWord(sal_Int32 &rSttPos, sal_Int32 nEndPos, SvxAutoCorrect &rACorrect, OUString *pPara) override
Definition: acorrect.cxx:371
void * p
SwPaM & m_rCursor
Definition: acorrect.hxx:51
bool IsAutoFormatRedline() const
Definition: doc.hxx:1446
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:358
void GotoPrevLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1444
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:167
uno::Reference< linguistic2::XHyphenator > GetHyphenator()
Definition: swtypes.cxx:57
bool DontExpand() const
Definition: txatbase.hxx:98
virtual void SetAttr(sal_Int32 nStt, sal_Int32 nEnd, sal_uInt16 nSlotId, SfxPoolItem &) override
Definition: acorrect.cxx:287
virtual bool Delete(sal_Int32 nStt, sal_Int32 nEnd) override
Definition: acorrect.cxx:144
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:476
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:2502
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:160
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
bool GetPreviewString(const OUString &sFormatString, double fPreviewNumber, OUString &sOutString, const Color **ppColor, LanguageType eLnge, bool bUseStarFormat=false)
virtual bool DeleteAndJoin(SwPaM &)=0
complete delete of a given PaM
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:92
virtual bool Replace(sal_Int32 nPos, const OUString &rText) override
Definition: acorrect.cxx:179
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1300
sal_uInt16 nPos
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1318
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:864