LibreOffice Module sw (master)  1
autofmt.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 <osl/diagnose.h>
23 #include <unotools/charclass.hxx>
24 
25 #include <editeng/boxitem.hxx>
26 #include <editeng/lrspitem.hxx>
28 #include <editeng/adjustitem.hxx>
29 #include <editeng/tstpitem.hxx>
30 #include <editeng/fontitem.hxx>
31 #include <editeng/langitem.hxx>
32 #include <editeng/acorrcfg.hxx>
33 #include <o3tl/string_view.hxx>
34 
35 #include <swwait.hxx>
36 #include <fmtpdsc.hxx>
37 #include <doc.hxx>
38 #include <IDocumentUndoRedo.hxx>
41 #include <redline.hxx>
42 #include <unocrsr.hxx>
43 #include <docary.hxx>
44 #include <editsh.hxx>
45 #include <index.hxx>
46 #include <pam.hxx>
47 #include <swundo.hxx>
48 #include <poolfmt.hxx>
49 #include <ndtxt.hxx>
50 #include <rootfrm.hxx>
51 #include <txtfrm.hxx>
52 #include <frminf.hxx>
53 #include <pagedesc.hxx>
54 #include <paratr.hxx>
55 #include <acorrect.hxx>
56 #include <shellres.hxx>
57 #include <section.hxx>
58 #include <frmatr.hxx>
59 #include <charatr.hxx>
60 #include <mdiexp.hxx>
61 #include <strings.hrc>
62 #include <comcore.hxx>
63 #include <numrule.hxx>
64 #include <itabenum.hxx>
65 
66 #include <memory>
67 
68 using namespace ::com::sun::star;
69 
70 //JP 16.12.99: definition:
71 // from pos cPosEnDash to cPosEmDash all chars changed to em dashes,
72 // from pos cPosEmDash to cPosEnd all chars changed to em dashes
73 // all other chars are changed to the user configuration
74 
75 const sal_Unicode pBulletChar[6] = { '+', '*', '-', 0x2013, 0x2014, 0 };
76 const int cnPosEnDash = 2, cnPosEmDash = 4;
77 
80 
82 
83 // Number of num-/bullet-paragraph templates. MAXLEVEL will soon be raised
84 // to x, but not the number of templates. (Artifact from <= 4.0)
85 const sal_uInt16 cnNumBullColls = 4;
86 
88 {
90  SwPaM m_aDelPam; // a Pam that can be used
91  SwNodeIndex m_aNdIdx; // the index on the current TextNode
92  SwNodeIndex m_aEndNdIdx; // index on the end of the area
93 
96  SwTextNode* m_pCurTextNd; // the current TextNode
97  SwTextFrame* m_pCurTextFrame; // frame of the current TextNode
98  bool m_bIsRightToLeft; // text direction of the current frame
99  SwNodeOffset m_nEndNdIdx; // for the percentage-display
100  mutable std::unique_ptr<CharClass> m_pCharClass; // Character classification
102 
104 
105  enum
106  {
107  NONE = 0,
108  DELIM = 1,
109  DIGIT = 2,
110  CHG = 4,
116  };
117 
118  bool m_bEnd : 1;
119  bool m_bMoreLines : 1;
120 
122  {
123  if( !m_pCharClass || eLang != m_eCharClassLang )
124  {
125  m_pCharClass.reset( new CharClass( LanguageTag( eLang ) ) );
126  m_eCharClassLang = eLang;
127  }
128  return *m_pCharClass;
129  }
130 
131  static bool IsSpace( const sal_Unicode c )
132  { return (' ' == c || '\t' == c || 0x0a == c|| 0x3000 == c /* Jap. space */); }
133 
134  void SetColl( sal_uInt16 nId, bool bHdLineOrText = false );
135  void GoNextPara();
136  static bool HasObjects(const SwTextFrame &);
137 
138  // TextNode methods
139  const SwTextFrame * GetNextNode(bool isCheckEnd = true) const;
140  static bool IsEmptyLine(const SwTextFrame & rFrame)
141  {
142  return rFrame.GetText().isEmpty()
143  || rFrame.GetText().getLength() == GetLeadingBlanks(rFrame.GetText());
144  }
145 
146  bool IsOneLine(const SwTextFrame &) const;
147  bool IsFastFullLine(const SwTextFrame &) const;
148  bool IsNoAlphaLine(const SwTextFrame &) const;
149  bool IsEnumericChar(const SwTextFrame &) const;
150  static bool IsBlanksInString(const SwTextFrame&);
151  sal_uInt16 CalcLevel(const SwTextFrame&, sal_uInt16 *pDigitLvl = nullptr) const;
152  sal_Int32 GetBigIndent(TextFrameIndex & rCurrentSpacePos) const;
153 
154  static OUString DelLeadingBlanks(const OUString& rStr);
155  static OUString DelTrailingBlanks( const OUString& rStr );
156  static sal_Int32 GetLeadingBlanks( const OUString& rStr );
157  static sal_Int32 GetTrailingBlanks( const OUString& rStr );
158 
159  bool IsFirstCharCapital(const SwTextFrame & rNd) const;
160  sal_uInt16 GetDigitLevel(const SwTextFrame& rFrame, TextFrameIndex& rPos,
161  OUString* pPrefix = nullptr, OUString* pPostfix = nullptr,
162  OUString* pNumTypes = nullptr ) const;
164  SwTextFrame* GetFrame( const SwTextNode& rTextNd ) const;
165  SwTextFrame * EnsureFormatted(SwTextFrame const&) const;
166 
167  void BuildIndent();
168  void BuildText();
169  void BuildTextIndent();
170  void BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel );
171  void BuildNegIndent( SwTwips nSpaces );
172  void BuildHeadLine( sal_uInt16 nLvl );
173 
174  static bool HasBreakAttr(const SwTextFrame &);
175  void DeleteSel( SwPaM& rPam );
176  void DeleteSelImpl(SwPaM & rDelPam, SwPaM & rPamToCorrect);
177  bool DeleteJoinCurNextPara(SwTextFrame const* pNextFrame, bool bIgnoreLeadingBlanks = false);
179  void DeleteLeadingTrailingBlanks( bool bStart = true, bool bEnd = true );
180  void DelEmptyLine( bool bTstNextPara = true );
183  void DelMoreLinesBlanks( bool bWithLineBreaks = false );
185  void JoinPrevPara();
187  void AutoCorrect(TextFrameIndex nSttPos = TextFrameIndex(0));
188 
189  bool CanJoin(const SwTextFrame * pNextFrame) const
190  {
191  return !m_bEnd && pNextFrame
192  && !IsEmptyLine(*pNextFrame)
193  && !IsNoAlphaLine(*pNextFrame)
194  && !IsEnumericChar(*pNextFrame)
195  // check the last / first nodes here...
196  && ((COMPLETE_STRING - 50 - pNextFrame->GetTextNodeFirst()->GetText().getLength())
197  > (m_pCurTextFrame->GetMergedPara()
198  ? m_pCurTextFrame->GetMergedPara()->pLastNode
199  : m_pCurTextNd)->GetText().getLength())
200  && !HasBreakAttr(*pNextFrame);
201  }
202 
204  static bool IsSentenceAtEnd(const SwTextFrame & rTextFrame);
205 
206  bool DoUnderline();
207  bool DoTable();
208 
209  void SetRedlineText_( sal_uInt16 nId );
210  bool SetRedlineText( sal_uInt16 nId ) {
211  if( m_aFlags.bWithRedlining )
212  SetRedlineText_( nId );
213  return true;
214  }
216  if( m_aFlags.bWithRedlining )
218  }
219 
220 public:
221  SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & rFlags,
222  SwNodeIndex const * pSttNd = nullptr, SwNodeIndex const * pEndNd = nullptr );
223 };
224 
225 static const sal_Unicode* StrChr( const sal_Unicode* pSrc, sal_Unicode c )
226 {
227  while( *pSrc && *pSrc != c )
228  ++pSrc;
229  return *pSrc ? pSrc : nullptr;
230 }
231 
233 {
234  // get the Frame
235  const SwContentFrame *pFrame = rTextNd.getLayoutFrame( m_pEditShell->GetLayout() );
236  assert(pFrame && "For Autoformat a Layout is needed");
237  return EnsureFormatted(*static_cast<SwTextFrame const*>(pFrame));
238 }
239 
241 {
242  SwTextFrame *const pFrame(const_cast<SwTextFrame*>(&rFrame));
243  if( m_aFlags.bAFormatByInput && !pFrame->isFrameAreaDefinitionValid() )
244  {
246  SwRect aTmpFrame( pFrame->getFrameArea() );
247  SwRect aTmpPrt( pFrame->getFramePrintArea() );
248  pFrame->Calc(pFrame->getRootFrame()->GetCurrShell()->GetOut());
249 
250  if( pFrame->getFrameArea() != aTmpFrame || pFrame->getFramePrintArea() != aTmpPrt ||
251  !pFrame->GetPaintSwRect().IsEmpty())
252  {
253  pFrame->SetCompletePaint();
254  }
255  }
256 
257  return pFrame->GetFormatted();
258 }
259 
260 void SwAutoFormat::SetRedlineText_( sal_uInt16 nActionId )
261 {
262  OUString sText;
263  sal_uInt16 nSeqNo = 0;
264  if( STR_AUTOFMTREDL_END > nActionId )
265  {
266  sText = SwViewShell::GetShellRes()->GetAutoFormatNameLst()[ nActionId ];
267  switch( nActionId )
268  {
271 
272  // AutoCorrect actions
284  nSeqNo = ++m_nRedlAutoFormatSeqId;
285  break;
286  }
287  }
288 #if OSL_DEBUG_LEVEL > 0
289  else
290  sText = "Action text is missing";
291 #endif
292 
293  m_pDoc->GetDocumentRedlineManager().SetAutoFormatRedlineComment( &sText, nSeqNo );
294 }
295 
297 {
298  SwNode* pNewNd = nullptr;
299  do {
300  // has to be checked twice before and after incrementation
301  if( m_aNdIdx.GetIndex() >= m_aEndNdIdx.GetIndex() )
302  {
303  m_bEnd = true;
304  return;
305  }
306 
307  sw::GotoNextLayoutTextFrame(m_aNdIdx, m_pEditShell->GetLayout());
308  if( m_aNdIdx.GetIndex() >= m_aEndNdIdx.GetIndex() )
309  {
310  m_bEnd = true;
311  return;
312  }
313  else
314  pNewNd = &m_aNdIdx.GetNode();
315 
316  // not a TextNode ->
317  // TableNode : skip table
318  // NoTextNode : skip nodes
319  // EndNode : at the end, terminate
320  if( pNewNd->IsEndNode() )
321  {
322  m_bEnd = true;
323  return;
324  }
325  else if( pNewNd->IsTableNode() )
326  m_aNdIdx = *pNewNd->EndOfSectionNode();
327  else if( pNewNd->IsSectionNode() )
328  {
329  const SwSection& rSect = pNewNd->GetSectionNode()->GetSection();
330  if( rSect.IsHiddenFlag() || rSect.IsProtectFlag() )
331  m_aNdIdx = *pNewNd->EndOfSectionNode();
332  }
333  } while( !pNewNd->IsTextNode() );
334 
335  if( !m_aFlags.bAFormatByInput )
336  ::SetProgressState( sal_Int32(m_aNdIdx.GetIndex() + m_nEndNdIdx - m_aEndNdIdx.GetIndex()),
337  m_pDoc->GetDocShell() );
338 
339  m_pCurTextNd = static_cast<SwTextNode*>(pNewNd);
340  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
341  m_bIsRightToLeft = m_pCurTextFrame->IsRightToLeft();
342 }
343 
345 {
346  // Is there something bound to the paragraph in the paragraph
347  // like Frames, DrawObjects, ...
348  SwNodeIndex node(*rFrame.GetTextNodeFirst());
349  do
350  {
351  if (!node.GetNode().GetAnchoredFlys().empty())
352  return true;
353  ++node;
354  }
355  while (sw::FrameContainsNode(rFrame, node.GetIndex()));
356  return false;
357 }
358 
359 const SwTextFrame* SwAutoFormat::GetNextNode(bool const isCheckEnd) const
360 {
361  SwNodeIndex tmp(m_aNdIdx);
362  sw::GotoNextLayoutTextFrame(tmp, m_pEditShell->GetLayout());
363  if ((isCheckEnd && m_aEndNdIdx <= tmp) || !tmp.GetNode().IsTextNode())
364  return nullptr;
365  // note: the returned frame is not necessarily formatted, have to call
366  // EnsureFormatted for that
367  return static_cast<SwTextFrame*>(tmp.GetNode().GetTextNode()->getLayoutFrame(m_pEditShell->GetLayout()));
368 }
369 
370 bool SwAutoFormat::IsOneLine(const SwTextFrame & rFrame) const
371 {
372  SwTextFrameInfo aFInfo( EnsureFormatted(rFrame) );
373  return aFInfo.IsOneLine();
374 }
375 
376 bool SwAutoFormat::IsFastFullLine(const SwTextFrame & rFrame) const
377 {
378  bool bRet = m_aFlags.bRightMargin;
379  if( bRet )
380  {
381  SwTextFrameInfo aFInfo( EnsureFormatted(rFrame) );
382  bRet = aFInfo.IsFilled( m_aFlags.nRightMargin );
383  }
384  return bRet;
385 }
386 
387 bool SwAutoFormat::IsEnumericChar(const SwTextFrame& rFrame) const
388 {
389  const OUString& rText = rFrame.GetText();
390  TextFrameIndex nBlanks(GetLeadingBlanks(rText));
391  const TextFrameIndex nLen = TextFrameIndex(rText.getLength()) - nBlanks;
392  if( !nLen )
393  return false;
394 
395  // -, +, * separated by blank ??
396  if (TextFrameIndex(2) < nLen && IsSpace(rText[sal_Int32(nBlanks) + 1]))
397  {
398  if (StrChr(pBulletChar, rText[sal_Int32(nBlanks)]))
399  return true;
400  // Should there be a symbol font at the position?
401  SwTextFrameInfo aFInfo( EnsureFormatted(rFrame) );
402  if (aFInfo.IsBullet(nBlanks))
403  return true;
404  }
405 
406  // 1.) / 1. / 1.1.1 / (1). / (1) / ...
407  return USHRT_MAX != GetDigitLevel(rFrame, nBlanks);
408 }
409 
411 {
412  // Search more than 5 consecutive blanks/tabs in the string.
413  OUString sTmp( DelLeadingBlanks(rFrame.GetText()) );
414  const sal_Int32 nLen = sTmp.getLength();
415  sal_Int32 nIdx = 0;
416  while (nIdx < nLen)
417  {
418  // Skip non-blanks
419  while (nIdx < nLen && !IsSpace(sTmp[nIdx])) ++nIdx;
420  if (nIdx == nLen)
421  return false;
422  // Then count consecutive blanks
423  const sal_Int32 nFirst = nIdx;
424  while (nIdx < nLen && IsSpace(sTmp[nIdx])) ++nIdx;
425  // And exit if enough consecutive blanks were found
426  if (nIdx-nFirst > 5)
427  return true;
428  }
429  return false;
430 }
431 
432 sal_uInt16 SwAutoFormat::CalcLevel(const SwTextFrame & rFrame,
433  sal_uInt16 *const pDigitLvl) const
434 {
435  sal_uInt16 nLvl = 0, nBlnk = 0;
436  const OUString& rText = rFrame.GetText();
437  if( pDigitLvl )
438  *pDigitLvl = USHRT_MAX;
439 
441  {
442  if( m_aFlags.bAFormatByInput )
443  {
444  // this is very non-obvious: on the *first* invocation of
445  // AutoFormat, the node will have the tabs (any number) converted
446  // to a fixed indent in BuildTextIndent(), and the number of tabs
447  // is stored in the node;
448  // on the *second* invocation of AutoFormat, CalcLevel() will
449  // retrieve the stored number, and it will be used by
450  // BuildHeadLine() to select the corresponding heading style.
451  nLvl = rFrame.GetTextNodeForParaProps()->GetAutoFormatLvl();
452  const_cast<SwTextNode *>(rFrame.GetTextNodeForParaProps())->SetAutoFormatLvl(0);
453  if( nLvl )
454  return nLvl;
455  }
456  ++nLvl;
457  }
458 
459  for (TextFrameIndex n(0),
460  nEnd(rText.getLength()); n < nEnd; ++n)
461  {
462  switch (rText[sal_Int32(n)])
463  {
464  case ' ': if( 3 == ++nBlnk )
465  {
466  ++nLvl;
467  nBlnk = 0;
468  }
469  break;
470  case '\t': ++nLvl;
471  nBlnk = 0;
472  break;
473  default:
474  if( pDigitLvl )
475  // test 1.) / 1. / 1.1.1 / (1). / (1) / ...
476  *pDigitLvl = GetDigitLevel(rFrame, n);
477  return nLvl;
478  }
479  }
480  return nLvl;
481 }
482 
483 sal_Int32 SwAutoFormat::GetBigIndent(TextFrameIndex & rCurrentSpacePos) const
484 {
485  SwTextFrameInfo aFInfo( m_pCurTextFrame );
486  const SwTextFrame* pNextFrame = nullptr;
487 
488  if( !m_bMoreLines )
489  {
490  pNextFrame = GetNextNode();
491  if (!CanJoin(pNextFrame) || !IsOneLine(*pNextFrame))
492  return 0;
493 
494  pNextFrame = EnsureFormatted(*pNextFrame);
495  }
496 
497  return aFInfo.GetBigIndent( rCurrentSpacePos, pNextFrame );
498 }
499 
500 bool SwAutoFormat::IsNoAlphaLine(const SwTextFrame & rFrame) const
501 {
502  const OUString& rStr = rFrame.GetText();
503  if( rStr.isEmpty() )
504  return false;
505  // or better: determine via number of AlphaNum and !AlphaNum characters
506  sal_Int32 nANChar = 0, nBlnk = 0;
507 
508  for (TextFrameIndex n(0),
509  nEnd(rStr.getLength()); n < nEnd; ++n)
510  if (IsSpace(rStr[sal_Int32(n)]))
511  ++nBlnk;
512  else
513  {
514  auto const pair = rFrame.MapViewToModel(n);
515  CharClass& rCC = GetCharClass(pair.first->GetSwAttrSet().GetLanguage().GetLanguage());
516  if (rCC.isLetterNumeric(rStr, sal_Int32(n)))
517  ++nANChar;
518  }
519 
520  // If there are 75% of non-alphanumeric characters, then true
521  sal_uLong nLen = rStr.getLength() - nBlnk;
522  nLen = ( nLen * 3 ) / 4; // long overflow, if the strlen > sal_uInt16
523  return sal_Int32(nLen) < (rStr.getLength() - nANChar - nBlnk);
524 }
525 
527 {
528  if( !m_aFlags.bSetBorder )
529  return false;
530 
531  OUString const& rText(m_pCurTextFrame->GetText());
532  int eState = 0;
533  sal_Int32 nCnt = 0;
534  while (nCnt < rText.getLength())
535  {
536  int eTmp = 0;
537  switch (rText[nCnt])
538  {
539  case '-': eTmp = 1; break;
540  case '_': eTmp = 2; break;
541  case '=': eTmp = 3; break;
542  case '*': eTmp = 4; break;
543  case '~': eTmp = 5; break;
544  case '#': eTmp = 6; break;
545  default:
546  return false;
547  }
548  if( 0 == eState )
549  eState = eTmp;
550  else if( eState != eTmp )
551  return false;
552  ++nCnt;
553  }
554 
555  if( 2 < nCnt )
556  {
557  // then underline the previous paragraph if one exists
558  DelEmptyLine( false ); // -> point will be on end of current paragraph
559  // WARNING: rText may be deleted now, m_pCurTextFrame may be nullptr
560  m_aDelPam.SetMark();
561  // apply to last node & rely on InsertItemSet to apply it to props-node
562  m_aDelPam.GetMark()->nContent = 0;
563 
565  switch( eState )
566  {
567  case 1: // single, hairline
568  aLine.SetBorderLineStyle(SvxBorderLineStyle::SOLID);
570  break;
571  case 2: // single, thin
572  aLine.SetBorderLineStyle(SvxBorderLineStyle::SOLID);
574  break;
575  case 3: // double, thin
576  aLine.SetBorderLineStyle(SvxBorderLineStyle::DOUBLE);
578  break;
579  case 4: // double, thick/thin
580  aLine.SetBorderLineStyle(SvxBorderLineStyle::THICKTHIN_SMALLGAP);
582  break;
583  case 5: // double, thin/thick
584  aLine.SetBorderLineStyle(SvxBorderLineStyle::THINTHICK_SMALLGAP);
586  break;
587  case 6: // double, medium
588  aLine.SetBorderLineStyle(SvxBorderLineStyle::DOUBLE);
590  break;
591  }
593  RES_BOX, RES_BOX> aSet(m_pDoc->GetAttrPool());
594  aSet.Put( SwParaConnectBorderItem( false ) );
595  SvxBoxItem aBox( RES_BOX );
596  aBox.SetLine( &aLine, SvxBoxItemLine::BOTTOM );
597  aBox.SetDistance(42, SvxBoxItemLine::BOTTOM ); // ~0,75 mm
598  aSet.Put(aBox);
599  m_pDoc->getIDocumentContentOperations().InsertItemSet(m_aDelPam, aSet,
600  SetAttrMode::DEFAULT, m_pEditShell->GetLayout());
601 
602  m_aDelPam.DeleteMark();
603  }
604  return 2 < nCnt;
605 }
606 
608 {
609  if( !m_aFlags.bCreateTable || !m_aFlags.bAFormatByInput ||
610  m_pCurTextNd->FindTableNode() )
611  return false;
612 
613  const OUString& rTmp = m_pCurTextFrame->GetText();
614  TextFrameIndex nSttPlus(GetLeadingBlanks(rTmp));
615  TextFrameIndex nEndPlus(GetTrailingBlanks(rTmp));
616  sal_Unicode cChar;
617 
618  if (TextFrameIndex(2) > nEndPlus - nSttPlus
619  || ('+' != (cChar = rTmp[sal_Int32(nSttPlus)]) && '|' != cChar)
620  || ('+' != (cChar = rTmp[sal_Int32(nEndPlus) - 1]) && '|' != cChar))
621  return false;
622 
623  SwTextFrameInfo aInfo( m_pCurTextFrame );
624 
625  TextFrameIndex n = nSttPlus;
626  std::vector<sal_uInt16> aPosArr;
627 
628  while (n < TextFrameIndex(rTmp.getLength()))
629  {
630  switch (rTmp[sal_Int32(n)])
631  {
632  case '-':
633  case '_':
634  case '=':
635  case ' ':
636  case '\t':
637  break;
638 
639  case '+':
640  case '|':
641  aPosArr.push_back( o3tl::narrowing<sal_uInt16>(aInfo.GetCharPos(n)) );
642  break;
643 
644  default:
645  return false;
646  }
647  if( ++n == nEndPlus )
648  break;
649  }
650 
651  if( 1 < aPosArr.size() )
652  {
653  // get the text node's alignment
654  sal_uInt16 nColCnt = aPosArr.size() - 1;
655  SwTwips nSttPos = aPosArr[ 0 ];
656  sal_Int16 eHori;
657  switch (m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().GetAdjust().GetAdjust())
658  {
659  case SvxAdjust::Center: eHori = text::HoriOrientation::CENTER; break;
660  case SvxAdjust::Right: eHori = text::HoriOrientation::RIGHT; break;
661 
662  default:
663  if( nSttPos )
664  {
666  // then - as last - we need to add the current frame width into the array
667  aPosArr.push_back( o3tl::narrowing<sal_uInt16>(m_pCurTextFrame->getFrameArea().Width()) );
668  }
669  else
670  eHori = text::HoriOrientation::LEFT;
671  break;
672  }
673 
674  // then create a table that matches the character
675  DelEmptyLine();
676  // WARNING: rTmp may be deleted now, m_pCurTextFrame may be nullptr
677  SwNodeIndex aIdx( m_aDelPam.GetPoint()->nNode );
678  m_aDelPam.Move( fnMoveForward );
680  *m_aDelPam.GetPoint(), 1, nColCnt, eHori,
681  nullptr, &aPosArr );
682  m_aDelPam.GetPoint()->nNode = aIdx;
683  }
684  return 1 < aPosArr.size();
685 }
686 
687 OUString SwAutoFormat::DelLeadingBlanks( const OUString& rStr )
688 {
689  sal_Int32 nL, n;
690  for( nL = rStr.getLength(), n = 0; n < nL && IsSpace( rStr[n] ); ++n )
691  ;
692  if( n ) // no Spaces
693  return rStr.copy(n);
694  return rStr;
695 }
696 
697 OUString SwAutoFormat::DelTrailingBlanks( const OUString& rStr )
698 {
699  sal_Int32 nL = rStr.getLength(), n = nL;
700  if( !nL )
701  return rStr;
702 
703  while( --n && IsSpace( rStr[ n ] ) )
704  ;
705  if( n+1 != nL ) // no Spaces
706  return rStr.copy( 0, n+1 );
707  return rStr;
708 }
709 
710 sal_Int32 SwAutoFormat::GetLeadingBlanks( const OUString& rStr )
711 {
712  sal_Int32 nL;
713  sal_Int32 n;
714 
715  for( nL = rStr.getLength(), n = 0; n < nL && IsSpace( rStr[ n ] ); ++n )
716  ;
717  return n;
718 }
719 
720 sal_Int32 SwAutoFormat::GetTrailingBlanks( const OUString& rStr )
721 {
722  sal_Int32 nL = rStr.getLength(), n = nL;
723  if( !nL )
724  return 0;
725 
726  while( --n && IsSpace( rStr[ n ] ) )
727  ;
728  return ++n;
729 }
730 
732 {
733  const OUString& rText = rFrame.GetText();
734  for (TextFrameIndex n(0),
735  nEnd(rText.getLength()); n < nEnd; ++n)
736  if (!IsSpace(rText[sal_Int32(n)]))
737  {
738  auto const pair = rFrame.MapViewToModel(n);
739  CharClass& rCC = GetCharClass( pair.first->GetSwAttrSet().
740  GetLanguage().GetLanguage() );
741  sal_Int32 nCharType = rCC.getCharacterType(rText, sal_Int32(n));
742  return CharClass::isLetterType( nCharType ) &&
743  0 != ( i18n::KCharacterType::UPPER &
744  nCharType );
745  }
746  return false;
747 }
748 
749 sal_uInt16
751  OUString* pPrefix, OUString* pPostfix, OUString* pNumTypes ) const
752 {
753 
754  // check for 1.) / 1. / 1.1.1 / (1). / (1) / ...
755  const OUString& rText = rFrame.GetText();
756  sal_Int32 nPos(rPos);
757  int eScan = NONE;
758 
759  sal_uInt16 nStart = 0;
760  sal_uInt8 nDigitLvl = 0, nDigitCnt = 0;
761  // count number of parenthesis to assure a sensible order is found
762  sal_uInt16 nOpeningParentheses = 0;
763  sal_uInt16 nClosingParentheses = 0;
764 
765  while (nPos < rText.getLength() && nDigitLvl < MAXLEVEL - 1)
766  {
767  auto const pair = rFrame.MapViewToModel(TextFrameIndex(nPos));
768  CharClass& rCC = GetCharClass(pair.first->GetSwAttrSet().GetLanguage().GetLanguage());
769  const sal_Unicode cCurrentChar = rText[nPos];
770  if( ('0' <= cCurrentChar && '9' >= cCurrentChar) ||
771  (0xff10 <= cCurrentChar && 0xff19 >= cCurrentChar) )
772  {
773  if( eScan & DELIM )
774  {
775  if( eScan & CHG ) // not if it starts with a number
776  {
777  ++nDigitLvl;
778  if( pPostfix )
779  *pPostfix += "\x01";
780  }
781 
782  if( pNumTypes )
783  *pNumTypes += OUStringChar(sal_Unicode('0' + SVX_NUM_ARABIC));
784 
785  eScan = eScan | CHG;
786  }
787  else if( pNumTypes && !(eScan & DIGIT) )
788  *pNumTypes += OUStringChar(sal_Unicode('0' + SVX_NUM_ARABIC));
789 
790  eScan &= ~DELIM; // remove Delim
791  if( 0 != (eScan & ~CHG) && DIGIT != (eScan & ~CHG))
792  return USHRT_MAX;
793 
794  eScan |= DIGIT; // add Digit
795  if( 3 == ++nDigitCnt ) // more than 2 numbers are not an enum anymore
796  return USHRT_MAX;
797 
798  nStart *= 10;
799  nStart += cCurrentChar <= '9' ? cCurrentChar - '0' : cCurrentChar - 0xff10;
800  }
801  else if( rCC.isAlpha( rText, nPos ) )
802  {
803  bool bIsUpper =
804  0 != ( i18n::KCharacterType::UPPER &
805  rCC.getCharacterType( rText, nPos ));
806  sal_Unicode cLow = rCC.lowercase(rText, nPos, 1)[0], cNumTyp;
807  int eTmpScan;
808 
809  // Roman numbers are "mdclxvi". Since we want to start numbering with c or d more often,
810  // convert first to characters and later to roman numbers if needed.
811  if( 256 > cLow && strchr( "mdclxvi", cLow ) )
812  {
813  if( bIsUpper )
814  {
815  cNumTyp = '0' + SVX_NUM_ROMAN_UPPER;
816  eTmpScan = UPPER_ROMAN;
817  }
818  else
819  {
820  cNumTyp = '0' + SVX_NUM_ROMAN_LOWER;
821  eTmpScan = LOWER_ROMAN;
822  }
823  }
824  else if( bIsUpper )
825  {
826  cNumTyp = '0' + SVX_NUM_CHARS_UPPER_LETTER;
827  eTmpScan = UPPER_ALPHA;
828  }
829  else
830  {
831  cNumTyp = '0' + SVX_NUM_CHARS_LOWER_LETTER;
832  eTmpScan = LOWER_ALPHA;
833  }
834 
835  // Switch to roman numbers (only for c/d!)
836  if( 1 == nDigitCnt && ( eScan & (UPPER_ALPHA|LOWER_ALPHA) ) &&
837  ( 3 == nStart || 4 == nStart) && 256 > cLow &&
838  strchr( "mdclxvi", cLow ) &&
839  (( eScan & UPPER_ALPHA ) ? (eTmpScan & (UPPER_ALPHA|UPPER_ROMAN))
840  : (eTmpScan & (LOWER_ALPHA|LOWER_ROMAN))) )
841  {
842  sal_Unicode c = '0';
843  nStart = 3 == nStart ? 100 : 500;
844  if( UPPER_ALPHA == eTmpScan )
845  {
846  eTmpScan = UPPER_ROMAN;
847  c += SVX_NUM_ROMAN_UPPER;
848  }
849  else
850  {
851  eTmpScan = LOWER_ROMAN;
852  c += SVX_NUM_ROMAN_LOWER;
853  }
854 
855  eScan = (eScan & ~(UPPER_ALPHA|LOWER_ALPHA)) | eTmpScan;
856  if( pNumTypes )
857  (*pNumTypes) = pNumTypes->replaceAt( pNumTypes->getLength() - 1, 1, rtl::OUStringChar(c) );
858  }
859 
860  if( eScan & DELIM )
861  {
862  if( eScan & CHG ) // not if it starts with a number
863  {
864  ++nDigitLvl;
865  if( pPostfix )
866  *pPostfix += "\x01";
867  }
868 
869  if( pNumTypes )
870  *pNumTypes += OUStringChar(cNumTyp);
871  eScan = eScan | CHG;
872  }
873  else if( pNumTypes && !(eScan & eTmpScan) )
874  *pNumTypes += OUStringChar(cNumTyp);
875 
876  eScan &= ~DELIM; // remove Delim
877 
878  // if another type is set, stop here
879  if( 0 != ( eScan & ~CHG ) && eTmpScan != ( eScan & ~CHG ))
880  return USHRT_MAX;
881 
882  if( eTmpScan & (UPPER_ALPHA | LOWER_ALPHA) )
883  {
884  // allow characters only if they appear once
885  return USHRT_MAX;
886  }
887  else
888  {
889  // roman numbers, check if valid characters
890  sal_uInt16 nVal;
891  bool bError = false;
892  switch( cLow )
893  {
894  case 'm': nVal = 1000; goto CHECK_ROMAN_1;
895  case 'd': nVal = 500; goto CHECK_ROMAN_5;
896  case 'c': nVal = 100; goto CHECK_ROMAN_1;
897  case 'l': nVal = 50; goto CHECK_ROMAN_5;
898  case 'x': nVal = 10; goto CHECK_ROMAN_1;
899  case 'v': nVal = 5; goto CHECK_ROMAN_5;
900 
901 CHECK_ROMAN_1:
902  {
903  int nMod5 = nStart % (nVal * 5);
904  int nLast = nStart % nVal;
905  int n10 = nVal / 10;
906 
907  if( nMod5 == ((3 * nVal) + n10 ) ||
908  nMod5 == ((4 * nVal) + n10 ) ||
909  nLast == n10 )
910  nStart = o3tl::narrowing<sal_uInt16>(nStart + (n10 * 8));
911  else if( nMod5 == 0 ||
912  nMod5 == (1 * nVal) ||
913  nMod5 == (2 * nVal) )
914  nStart = nStart + nVal;
915  else
916  bError = true;
917  }
918  break;
919 
920 CHECK_ROMAN_5:
921  {
922  if( ( nStart / nVal ) & 1 )
923  bError = true;
924  else
925  {
926  int nMod = nStart % nVal;
927  int n10 = nVal / 5;
928  if( n10 == nMod )
929  nStart = o3tl::narrowing<sal_uInt16>(nStart + (3 * n10));
930  else if( 0 == nMod )
931  nStart = nStart + nVal;
932  else
933  bError = true;
934  }
935  }
936  break;
937 
938  case 'i':
939  if( nStart % 5 >= 3 )
940  bError = true;
941  else
942  nStart += 1;
943  break;
944 
945  default:
946  bError = true;
947  }
948 
949  if( bError )
950  return USHRT_MAX;
951  }
952  eScan |= eTmpScan; // add Digit
953  ++nDigitCnt;
954  }
955  else if( (256 > cCurrentChar &&
956  strchr( ".)(", cCurrentChar )) ||
957  0x3002 == cCurrentChar /* Chinese trad. dot */||
958  0xff0e == cCurrentChar /* Japanese dot */||
959  0xFF08 == cCurrentChar /* opening bracket Chin./Jap.*/||
960  0xFF09 == cCurrentChar )/* closing bracket Chin./Jap. */
961  {
962  if(cCurrentChar == '(' || cCurrentChar == 0xFF09)
963  nOpeningParentheses++;
964  else if(cCurrentChar == ')'|| cCurrentChar == 0xFF08)
965  nClosingParentheses++;
966  // only if no numbers were read until here
967  if( pPrefix && !( eScan & ( NO_DELIM | CHG )) )
968  *pPrefix += OUStringChar(rText[nPos]);
969  else if( pPostfix )
970  *pPostfix += OUStringChar(rText[nPos]);
971 
972  if( NO_DELIM & eScan )
973  {
974  eScan |= CHG;
975  if( pPrefix )
976  *pPrefix += "\x01" + OUString::number( nStart );
977  }
978  eScan &= ~NO_DELIM; // remove Delim
979  eScan |= DELIM; // add Digit
980  nDigitCnt = 0;
981  nStart = 0;
982  }
983  else
984  break;
985  ++nPos;
986  }
987  if (!( CHG & eScan ) || rPos == TextFrameIndex(nPos) ||
988  nPos == rText.getLength() || !IsSpace(rText[nPos]) ||
989  (nOpeningParentheses > nClosingParentheses))
990  return USHRT_MAX;
991 
992  if( (NO_DELIM & eScan) && pPrefix ) // do not forget the last one
993  *pPrefix += "\x01" + OUString::number( nStart );
994 
995  rPos = TextFrameIndex(nPos);
996  return nDigitLvl; // 0 .. 9 (MAXLEVEL - 1)
997 }
998 
999 void SwAutoFormat::SetColl( sal_uInt16 nId, bool bHdLineOrText )
1000 {
1001  m_aDelPam.DeleteMark();
1002  m_aDelPam.GetPoint()->nNode = *m_pCurTextFrame->GetTextNodeForParaProps();
1003  m_aDelPam.GetPoint()->nContent.Assign(m_aDelPam.GetPoint()->nNode.GetNode().GetContentNode(), 0);
1004 
1005  // keep hard tabs, alignment, language, hyphenation, DropCaps and nearly all frame attributes
1010  RES_BACKGROUND, RES_SHADOW> aSet(m_pDoc->GetAttrPool());
1011 
1012  if (m_aDelPam.GetPoint()->nNode.GetNode().GetTextNode()->HasSwAttrSet())
1013  {
1014  aSet.Put(*m_aDelPam.GetPoint()->nNode.GetNode().GetTextNode()->GetpSwAttrSet());
1015  // take HeaderLine/TextBody only if centered or right aligned, otherwise only justification
1016  if( SvxAdjustItem const * pAdj = aSet.GetItemIfSet( RES_PARATR_ADJUST, false) )
1017  {
1018  SvxAdjust eAdj = pAdj->GetAdjust();
1019  if( bHdLineOrText ? (SvxAdjust::Right != eAdj &&
1020  SvxAdjust::Center != eAdj)
1021  : SvxAdjust::Block != eAdj )
1022  aSet.ClearItem( RES_PARATR_ADJUST );
1023  }
1024  }
1025 
1026  m_pDoc->SetTextFormatCollByAutoFormat( *m_aDelPam.GetPoint(), nId, &aSet );
1027 }
1028 
1029 static bool HasSelBlanks(
1030  SwTextFrame const*const pStartFrame, TextFrameIndex & rStartIndex,
1031  SwTextFrame const*const pEndFrame, TextFrameIndex & rEndIndex)
1032 {
1033  if (TextFrameIndex(0) < rEndIndex
1034  && rEndIndex < TextFrameIndex(pEndFrame->GetText().getLength())
1035  && ' ' == pEndFrame->GetText()[sal_Int32(rEndIndex) - 1])
1036  {
1037  --rEndIndex;
1038  return true;
1039  }
1040  if (rStartIndex < TextFrameIndex(pStartFrame->GetText().getLength())
1041  && ' ' == pStartFrame->GetText()[sal_Int32(rStartIndex)])
1042  {
1043  ++rStartIndex;
1044  return true;
1045  }
1046  return false;
1047 }
1048 
1050 {
1051  const SfxItemSet *const pSet = rTextFrame.GetTextNodeFirst()->GetpSwAttrSet();
1052  if( !pSet )
1053  return false;
1054 
1055  const SvxFormatBreakItem* pBreakItem = pSet->GetItemIfSet( RES_BREAK, false );
1056  if( pBreakItem && SvxBreak::NONE != pBreakItem->GetBreak() )
1057  return true;
1058 
1059  const SwFormatPageDesc* pItem = pSet->GetItemIfSet( RES_PAGEDESC, false );
1060  if( pItem && pItem->GetPageDesc()
1061  && UseOnPage::NONE != pItem->GetPageDesc()->GetUseOn() )
1062  return true;
1063  return false;
1064 }
1065 
1068 {
1069  const OUString& rStr = rTextFrame.GetText();
1070  sal_Int32 n = rStr.getLength();
1071  if( !n )
1072  return true;
1073 
1074  while( --n && IsSpace( rStr[ n ] ) )
1075  ;
1076  return '.' == rStr[ n ];
1077 }
1078 
1080 void SwAutoFormat::DeleteLeadingTrailingBlanks(bool bStart, bool bEnd)
1081 {
1082  if( !(m_aFlags.bAFormatByInput
1084  : m_aFlags.bAFormatDelSpacesAtSttEnd) )
1085  return;
1086 
1087  // delete blanks at the end of the current and at the beginning of the next one
1088  m_aDelPam.DeleteMark();
1089  TextFrameIndex nPos(GetLeadingBlanks(m_pCurTextFrame->GetText()));
1090  if (bStart && TextFrameIndex(0) != nPos)
1091  {
1092  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
1093  m_aDelPam.SetMark();
1094  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
1095  DeleteSel( m_aDelPam );
1096  m_aDelPam.DeleteMark();
1097  }
1098  nPos = TextFrameIndex(GetTrailingBlanks(m_pCurTextFrame->GetText()));
1099  if (bEnd && TextFrameIndex(m_pCurTextFrame->GetText().getLength()) != nPos)
1100  {
1101  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
1102  TextFrameIndex(m_pCurTextFrame->GetText().getLength()));
1103  m_aDelPam.SetMark();
1104  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
1105  DeleteSel( m_aDelPam );
1106  m_aDelPam.DeleteMark();
1107  }
1108 }
1109 
1110 namespace sw {
1111 
1112 bool GetRanges(std::vector<std::shared_ptr<SwUnoCursor>> & rRanges,
1113  SwDoc & rDoc, SwPaM const& rDelPam)
1114 {
1115  bool isNoRedline(true);
1118  if (!(rIDRA.GetRedlineFlags() & RedlineFlags::ShowDelete))
1119  {
1120  return isNoRedline;
1121  }
1122  rIDRA.GetRedline(*rDelPam.Start(), &tmp);
1123  SwPosition const* pCurrent(rDelPam.Start());
1124  for ( ; tmp < rIDRA.GetRedlineTable().size(); ++tmp)
1125  {
1126  SwRangeRedline const*const pRedline(rIDRA.GetRedlineTable()[tmp]);
1127  if (*rDelPam.End() <= *pRedline->Start())
1128  {
1129  break;
1130  }
1131  if (*pRedline->End() <= *rDelPam.Start())
1132  {
1133  continue;
1134  }
1135  if (pRedline->GetType() == RedlineType::Delete)
1136  {
1137  assert(*pRedline->Start() != *pRedline->End());
1138  isNoRedline = false;
1139  if (*pCurrent < *pRedline->Start())
1140  {
1141  rRanges.push_back(rDoc.CreateUnoCursor(*pCurrent));
1142  rRanges.back()->SetMark();
1143  *rRanges.back()->GetPoint() = *pRedline->Start();
1144  }
1145  pCurrent = pRedline->End();
1146  }
1147  }
1148  if (!isNoRedline && *pCurrent < *rDelPam.End())
1149  {
1150  rRanges.push_back(rDoc.CreateUnoCursor(*pCurrent));
1151  rRanges.back()->SetMark();
1152  *rRanges.back()->GetPoint() = *rDelPam.End();
1153  }
1154  return isNoRedline;
1155 }
1156 
1157 } // namespace sw
1158 
1160 {
1161  std::vector<std::shared_ptr<SwUnoCursor>> ranges; // need correcting cursor
1162  if (GetRanges(ranges, *m_pDoc, rDelPam))
1163  {
1164  DeleteSelImpl(rDelPam, rDelPam);
1165  }
1166  else
1167  {
1168  for (auto const& pCursor : ranges)
1169  {
1170  DeleteSelImpl(*pCursor, rDelPam);
1171  }
1172  }
1173 }
1174 
1175 void SwAutoFormat::DeleteSelImpl(SwPaM & rDelPam, SwPaM & rPamToCorrect)
1176 {
1177  if (m_aFlags.bWithRedlining || &rDelPam != &rPamToCorrect)
1178  {
1179  // Add to Shell-Cursor-Ring so that DelPam will be moved as well!
1180  SwPaM* pShCursor = m_pEditShell->GetCursor_();
1181  SwPaM aTmp( *m_pCurTextNd, 0, pShCursor );
1182 
1183  SwPaM* pPrev = rPamToCorrect.GetPrev();
1184  rPamToCorrect.GetRingContainer().merge( pShCursor->GetRingContainer() );
1185 
1186  m_pEditShell->DeleteSel( rDelPam );
1187 
1188  // and remove Pam again:
1189  SwPaM* p;
1190  SwPaM* pNext = &rPamToCorrect;
1191  do {
1192  p = pNext;
1193  pNext = p->GetNext();
1194  p->MoveTo( &rPamToCorrect );
1195  } while( p != pPrev );
1196 
1197  m_aNdIdx = aTmp.GetPoint()->nNode;
1198  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
1199  m_pCurTextFrame = GetFrame(*m_pCurTextNd); // keep it up to date
1200  }
1201  else
1202  m_pEditShell->DeleteSel( rDelPam );
1203 }
1204 
1206  bool const bIgnoreLeadingBlanks)
1207 {
1208  // delete blanks at the end of the current and at the beginning of the next one
1209  m_aDelPam.DeleteMark();
1210  TextFrameIndex nTrailingPos(GetTrailingBlanks(m_pCurTextFrame->GetText()));
1211 
1212  SwTextFrame const*const pEndFrame(pNextFrame ? pNextFrame : m_pCurTextFrame);
1213  TextFrameIndex nLeadingPos(0);
1214  if (pNextFrame)
1215  {
1216  nLeadingPos = TextFrameIndex(
1217  bIgnoreLeadingBlanks ? 0 : GetLeadingBlanks(pNextFrame->GetText()));
1218  }
1219  else
1220  {
1221  nLeadingPos = TextFrameIndex(m_pCurTextFrame->GetText().getLength());
1222  }
1223 
1224  // Is there a Blank at the beginning or end?
1225  // Do not delete it, it will be inserted again.
1226  bool bHasBlnks = HasSelBlanks(m_pCurTextFrame, nTrailingPos, pEndFrame, nLeadingPos);
1227 
1228  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nTrailingPos);
1229  m_aDelPam.SetMark();
1230  *m_aDelPam.GetPoint() = pEndFrame->MapViewToModelPos(nLeadingPos);
1231 
1232  if( *m_aDelPam.GetPoint() != *m_aDelPam.GetMark() )
1233  DeleteSel( m_aDelPam );
1234  m_aDelPam.DeleteMark();
1235  // note: keep m_aDelPam point at insert pos. for clients
1236 
1237  return !bHasBlnks;
1238 }
1239 
1240 void SwAutoFormat::DelEmptyLine( bool bTstNextPara )
1241 {
1243  // delete blanks in empty paragraph
1244  m_aDelPam.DeleteMark();
1245  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
1246  TextFrameIndex(0));
1247  m_aDelPam.SetMark();
1248 
1249  m_aDelPam.GetMark()->nNode = m_pCurTextFrame->GetTextNodeFirst()->GetIndex() - 1;
1250  SwTextNode* pTNd = m_aDelPam.GetNode( false ).GetTextNode();
1251  if( pTNd )
1252  // first use the previous text node
1253  m_aDelPam.GetMark()->nContent.Assign(pTNd, pTNd->GetText().getLength());
1254  else if( bTstNextPara )
1255  {
1256  // then try the next (at the beginning of a Doc, table cells, frames, ...)
1257  m_aDelPam.GetMark()->nNode = (m_pCurTextFrame->GetMergedPara()
1258  ? m_pCurTextFrame->GetMergedPara()->pLastNode
1259  : m_pCurTextNd
1260  )->GetIndex() + 1;
1261  pTNd = m_aDelPam.GetNode( false ).GetTextNode();
1262  if( pTNd )
1263  {
1264  m_aDelPam.GetMark()->nContent.Assign( pTNd, 0 );
1265  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
1266  TextFrameIndex(m_pCurTextFrame->GetText().getLength()));
1267  }
1268  }
1269  if( pTNd )
1270  { // join with previous or next paragraph
1271  DeleteSel(m_aDelPam);
1272  }
1273  assert(m_aDelPam.GetNode().IsTextNode());
1274  assert(!m_aDelPam.HasMark());
1275  m_aDelPam.SetMark(); // mark remains at join position
1276  m_pCurTextFrame = GetFrame(*m_aDelPam.GetNode().GetTextNode());
1277  // replace until the end of the merged paragraph
1278  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
1279  TextFrameIndex(m_pCurTextFrame->GetText().getLength()));
1280  if (*m_aDelPam.GetPoint() != *m_aDelPam.GetMark())
1281  { // tdf#137245 replace (not delete) to preserve any flys
1282  m_pDoc->getIDocumentContentOperations().ReplaceRange(m_aDelPam, "", false);
1283  }
1284 
1285  m_aDelPam.DeleteMark();
1286  ClearRedlineText();
1287  // note: this likely has deleted m_pCurTextFrame - update it...
1288  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
1289  m_pCurTextFrame = m_pCurTextNd ? GetFrame( *m_pCurTextNd ) : nullptr;
1290 }
1291 
1292 void SwAutoFormat::DelMoreLinesBlanks( bool bWithLineBreaks )
1293 {
1294  if( !(m_aFlags.bAFormatByInput
1296  : m_aFlags.bAFormatDelSpacesBetweenLines) )
1297  return;
1298 
1299  // delete all blanks on the left and right of the indentation
1300  m_aDelPam.DeleteMark();
1301 
1302  SwTextFrameInfo aFInfo( m_pCurTextFrame );
1303  std::vector<std::pair<TextFrameIndex, TextFrameIndex>> spaces;
1304  aFInfo.GetSpaces(spaces, !m_aFlags.bAFormatByInput || bWithLineBreaks);
1305 
1306  // tdf#123285 iterate backwards - delete invalidates following indexes
1307  for (auto iter = spaces.rbegin(); iter != spaces.rend(); ++iter)
1308  {
1309  auto & rSpaceRange(*iter);
1310  assert(rSpaceRange.first != rSpaceRange.second);
1311  bool const bHasBlanks = HasSelBlanks(
1312  m_pCurTextFrame, rSpaceRange.first,
1313  m_pCurTextFrame, rSpaceRange.second);
1314  if (rSpaceRange.first != rSpaceRange.second)
1315  {
1316  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(rSpaceRange.first);
1317  m_aDelPam.SetMark();
1318  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(rSpaceRange.second);
1319  DeleteSel(m_aDelPam);
1320  if (!bHasBlanks)
1321  {
1322  m_pDoc->getIDocumentContentOperations().InsertString(m_aDelPam, OUString(' '));
1323  }
1324  m_aDelPam.DeleteMark();
1325  }
1326  }
1327 }
1328 
1330 {
1331  m_aDelPam.DeleteMark();
1332  m_aDelPam.GetPoint()->nNode = *m_pCurTextFrame->GetTextNodeFirst();
1333  m_aDelPam.GetPoint()->nContent.Assign(m_pCurTextFrame->GetTextNodeFirst(), 0);
1334  m_aDelPam.SetMark();
1335 
1336  --m_aDelPam.GetPoint()->nNode;
1337  SwTextNode* pTNd = m_aDelPam.GetNode().GetTextNode();
1338  if( pTNd )
1339  {
1340  // use the previous text node first
1341  m_aDelPam.GetPoint()->nContent.Assign(pTNd, pTNd->GetText().getLength());
1342  DeleteSel( m_aDelPam );
1343  }
1344  m_aDelPam.DeleteMark();
1345 }
1346 
1348 {
1350 
1351  // read all succeeding paragraphs that belong to this indentation
1352  bool bBreak = true;
1353  if( m_bMoreLines )
1354  DelMoreLinesBlanks( true );
1355  else
1356  bBreak = !IsFastFullLine(*m_pCurTextFrame)
1357  || IsBlanksInString(*m_pCurTextFrame)
1358  || IsSentenceAtEnd(*m_pCurTextFrame);
1360  if( !bBreak )
1361  {
1363  const SwTextFrame * pNextFrame = GetNextNode();
1364  if (pNextFrame && !m_bEnd)
1365  {
1366  do {
1367  bBreak = !IsFastFullLine(*pNextFrame)
1368  || IsBlanksInString(*pNextFrame)
1369  || IsSentenceAtEnd(*pNextFrame);
1370  if (DeleteJoinCurNextPara(pNextFrame))
1371  {
1372  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
1373  }
1374  if( bBreak )
1375  break;
1376  pNextFrame = GetNextNode();
1377  }
1378  while (CanJoin(pNextFrame)
1379  && !CalcLevel(*pNextFrame));
1380  }
1381  }
1383  AutoCorrect();
1384 }
1385 
1387 {
1389  // read all succeeding paragraphs that belong to this indentation
1390  bool bBreak = true;
1391  if( m_bMoreLines )
1392  DelMoreLinesBlanks( true );
1393  else
1394  bBreak = !IsFastFullLine(*m_pCurTextFrame)
1395  || IsBlanksInString(*m_pCurTextFrame)
1396  || IsSentenceAtEnd(*m_pCurTextFrame);
1397 
1398  if( m_aFlags.bAFormatByInput )
1399  {
1400  const_cast<SwTextNode*>(m_pCurTextFrame->GetTextNodeForParaProps())->SetAutoFormatLvl(
1401  static_cast<sal_uInt8>(CalcLevel(*m_pCurTextFrame)));
1402  }
1403 
1405  if( !bBreak )
1406  {
1408  const SwTextFrame * pNextFrame = GetNextNode();
1409  while (CanJoin(pNextFrame) &&
1410  CalcLevel(*pNextFrame))
1411  {
1412  bBreak = !IsFastFullLine(*pNextFrame)
1413  || IsBlanksInString(*pNextFrame)
1414  || IsSentenceAtEnd(*pNextFrame);
1415  if (DeleteJoinCurNextPara(pNextFrame))
1416  {
1417  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
1418  }
1419  if( bBreak )
1420  break;
1421  pNextFrame = GetNextNode();
1422  }
1423  }
1425  AutoCorrect();
1426 }
1427 
1429 {
1431  // read all succeeding paragraphs that belong to this text without indentation
1432  bool bBreak = true;
1433  if( m_bMoreLines )
1435  else
1436  bBreak = !IsFastFullLine(*m_pCurTextFrame)
1437  || IsBlanksInString(*m_pCurTextFrame)
1438  || IsSentenceAtEnd(*m_pCurTextFrame);
1439  SetColl( RES_POOLCOLL_TEXT, true );
1440  if( !bBreak )
1441  {
1443  const SwTextFrame * pNextFrame = GetNextNode();
1444  while (CanJoin(pNextFrame) &&
1445  !CalcLevel(*pNextFrame))
1446  {
1447  bBreak = !IsFastFullLine(*pNextFrame)
1448  || IsBlanksInString(*pNextFrame)
1449  || IsSentenceAtEnd(*pNextFrame);
1450  if (DeleteJoinCurNextPara(pNextFrame))
1451  {
1452  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
1453  }
1454  if( bBreak )
1455  break;
1456  const SwTextFrame *const pCurrNode = pNextFrame;
1457  pNextFrame = GetNextNode();
1458  if (!pNextFrame || pCurrNode == pNextFrame)
1459  break;
1460  }
1461  }
1463  AutoCorrect();
1464 }
1465 
1466 void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
1467 {
1469 
1470  bool bBreak = true;
1471 
1472  // first, determine current indentation and frame width
1473  SwTwips nFrameWidth = m_pCurTextFrame->getFramePrintArea().Width();
1474  SwTwips nLeftTextPos;
1475  {
1476  TextFrameIndex nPos(0);
1477  while (nPos < TextFrameIndex(m_pCurTextFrame->GetText().getLength())
1478  && IsSpace(m_pCurTextFrame->GetText()[sal_Int32(nPos)]))
1479  {
1480  ++nPos;
1481  }
1482 
1483  SwTextFrameInfo aInfo( m_pCurTextFrame );
1484  nLeftTextPos = aInfo.GetCharPos(nPos);
1485  nLeftTextPos -= m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().GetLRSpace().GetLeft();
1486  }
1487 
1488  if( m_bMoreLines )
1490  else
1491  bBreak = !IsFastFullLine(*m_pCurTextFrame)
1492  || IsBlanksInString(*m_pCurTextFrame)
1493  || IsSentenceAtEnd(*m_pCurTextFrame);
1494  bool bRTL = m_pEditShell->IsInRightToLeftText();
1496 
1497  bool bChgBullet = false, bChgEnum = false;
1498  TextFrameIndex nAutoCorrPos(0);
1499 
1500  // if numbering is set, get the current one
1501  SwNumRule aRule( m_pDoc->GetUniqueNumRuleName(),
1502  // #i89178#
1504 
1505  const SwNumRule* pCur = nullptr;
1506  if (m_aFlags.bSetNumRule)
1507  {
1508  pCur = m_pCurTextFrame->GetTextNodeForParaProps()->GetNumRule();
1509  if (pCur)
1510  {
1511  aRule = *pCur;
1512  }
1513  }
1514 
1515  // replace bullet character with defined one
1516  const OUString& rStr = m_pCurTextFrame->GetText();
1517  TextFrameIndex nTextStt(0);
1518  const sal_Unicode* pFndBulletChr = nullptr;
1519  if (m_aFlags.bChgEnumNum && 2 < rStr.getLength())
1520  pFndBulletChr = StrChr(pBulletChar, rStr[sal_Int32(nTextStt)]);
1521  if (nullptr != pFndBulletChr && IsSpace(rStr[sal_Int32(nTextStt) + 1]))
1522  {
1523  if( m_aFlags.bAFormatByInput )
1524  {
1525  if( m_aFlags.bSetNumRule )
1526  {
1529  bChgBullet = true;
1530  // Was the format already somewhere adjusted?
1531  if( !aRule.GetNumFormat( nLvl ) )
1532  {
1533  int nBulletPos = pFndBulletChr - pBulletChar;
1534  sal_UCS4 cBullChar;
1535  const vcl::Font* pBullFnt( nullptr );
1536  if( nBulletPos < cnPosEnDash )
1537  {
1538  cBullChar = m_aFlags.cBullet;
1539  pBullFnt = &m_aFlags.aBulletFont;
1540  }
1541  else
1542  {
1543  cBullChar = nBulletPos < cnPosEmDash
1546  // #i63395#
1547  // Only apply user defined default bullet font
1549  {
1550  pBullFnt = &numfunc::GetDefBulletFont();
1551  }
1552  }
1553 
1554  sal_Int32 nAbsPos = lBulletIndent;
1555  SwTwips nSpaceSteps = nLvl
1556  ? nLeftTextPos / nLvl
1557  : lBulletIndent;
1558  for( sal_uInt8 n = 0; n < MAXLEVEL; ++n, nAbsPos = nAbsPos + nSpaceSteps )
1559  {
1560  SwNumFormat aFormat( aRule.Get( n ) );
1561  aFormat.SetBulletFont( pBullFnt );
1562  aFormat.SetBulletChar( cBullChar );
1563  aFormat.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
1564  // #i93908# clear suffix for bullet lists
1565  aFormat.SetPrefix(OUString());
1566  aFormat.SetSuffix(OUString());
1567  aFormat.SetFirstLineOffset( lBulletFirstLineOffset );
1568  aFormat.SetAbsLSpace( nAbsPos );
1569  if( !aFormat.GetCharFormat() )
1570  aFormat.SetCharFormat( pCFormat );
1571  if( bRTL )
1572  aFormat.SetNumAdjust( SvxAdjust::Right );
1573 
1574  aRule.Set( n, aFormat );
1575 
1576  if( n == nLvl &&
1577  nFrameWidth < ( nSpaceSteps * MAXLEVEL ) )
1578  nSpaceSteps = ( nFrameWidth - nLeftTextPos ) /
1579  ( MAXLEVEL - nLvl );
1580  }
1581  }
1582  }
1583  }
1584  else
1585  {
1586  bChgBullet = true;
1587  SetColl( o3tl::narrowing<sal_uInt16>(RES_POOLCOLL_BULLET_LEVEL1 + ( std::min( nLvl, cnNumBullColls ) * 4 )) );
1588  }
1589  }
1590  else
1591  {
1592  // Then it is a numbering
1593 
1594  //JP 21.11.97: The NumLevel is either the DigitLevel or, if the latter is not existent or 0,
1595  // it is determined by the indentation level.
1596 
1597  OUString aPostfix, aPrefix, aNumTypes;
1598  nDigitLevel = GetDigitLevel(*m_pCurTextFrame, nTextStt,
1599  &aPrefix, &aPostfix, &aNumTypes);
1600  if (USHRT_MAX != nDigitLevel)
1601  {
1602  bChgEnum = true;
1603 
1604  // Level 0 and Indentation, determine level by left indentation and default NumIndent
1605  if( !nDigitLevel && nLeftTextPos )
1606  nLvl = std::min( sal_uInt16( nLeftTextPos / lNumberIndent ),
1607  sal_uInt16( MAXLEVEL - 1 ) );
1608  else
1609  nLvl = nDigitLevel;
1610  }
1611 
1612  if( bChgEnum && m_aFlags.bSetNumRule )
1613  {
1614  if( !pCur ) // adjust NumRule if it is new
1615  {
1618 
1619  sal_Int32 nPrefixIdx{ 0 };
1620  if( !nDigitLevel )
1621  {
1622  SwNumFormat aFormat( aRule.Get( nLvl ) );
1623  aFormat.SetPrefix( aPrefix.getToken( 0, u'\x0001', nPrefixIdx ));
1624  aFormat.SetStart( o3tl::narrowing<sal_uInt16>(o3tl::toInt32(o3tl::getToken(aPrefix, 0, u'\x0001', nPrefixIdx ))));
1625  aFormat.SetSuffix( aPostfix.getToken( 0, u'\x0001' ));
1626  aFormat.SetIncludeUpperLevels( 0 );
1627 
1628  if( !aFormat.GetCharFormat() )
1629  aFormat.SetCharFormat( pCFormat );
1630 
1631  if( !aNumTypes.isEmpty() )
1632  aFormat.SetNumberingType(static_cast<SvxNumType>(aNumTypes[ 0 ] - '0'));
1633 
1634  if( bRTL )
1635  aFormat.SetNumAdjust( SvxAdjust::Right );
1636  aRule.Set( nLvl, aFormat );
1637  }
1638  else
1639  {
1640  auto const nSpaceSteps = nLvl ? nLeftTextPos / nLvl : 0;
1641  sal_uInt16 n;
1642  sal_Int32 nPostfixIdx{ 0 };
1643  for( n = 0; n <= nLvl; ++n )
1644  {
1645  SwNumFormat aFormat( aRule.Get( n ) );
1646 
1647  if( !n )
1648  aFormat.SetPrefix( aPrefix.getToken( 0, u'\x0001', nPrefixIdx )); // token 0, read only on first loop
1649  aFormat.SetStart( o3tl::narrowing<sal_uInt16>(o3tl::toInt32(o3tl::getToken(aPrefix, 0, u'\x0001', nPrefixIdx )) ));
1650  aFormat.SetSuffix( aPostfix.getToken( 0, u'\x0001', nPostfixIdx ));
1651  aFormat.SetIncludeUpperLevels( MAXLEVEL );
1652  if( n < aNumTypes.getLength() )
1653  aFormat.SetNumberingType(static_cast<SvxNumType>(aNumTypes[ n ] - '0'));
1654 
1655  aFormat.SetAbsLSpace( nSpaceSteps * n
1656  + lNumberIndent );
1657 
1658  if( !aFormat.GetCharFormat() )
1659  aFormat.SetCharFormat( pCFormat );
1660  if( bRTL )
1661  aFormat.SetNumAdjust( SvxAdjust::Right );
1662 
1663  aRule.Set( n, aFormat );
1664  }
1665 
1666  // Does it fit completely into the frame?
1667  bool bDefStep = nFrameWidth < (nSpaceSteps * MAXLEVEL);
1668  for( ; n < MAXLEVEL; ++n )
1669  {
1670  SwNumFormat aFormat( aRule.Get( n ) );
1671  aFormat.SetIncludeUpperLevels( MAXLEVEL );
1672  if( bDefStep )
1673  aFormat.SetAbsLSpace( nLeftTextPos +
1674  SwNumRule::GetNumIndent(static_cast<sal_uInt8>(n-nLvl)));
1675  else
1676  aFormat.SetAbsLSpace( nSpaceSteps * n
1677  + lNumberIndent );
1678  aRule.Set( n, aFormat );
1679  }
1680  }
1681  }
1682  }
1683  else if( !m_aFlags.bAFormatByInput )
1684  SetColl( o3tl::narrowing<sal_uInt16>(RES_POOLCOLL_NUM_LEVEL1 + ( std::min( nLvl, cnNumBullColls ) * 4 ) ));
1685  else
1686  bChgEnum = false;
1687  }
1688 
1689  if ( bChgEnum || bChgBullet )
1690  {
1691  m_aDelPam.DeleteMark();
1692  m_aDelPam.GetPoint()->nNode = *m_pCurTextFrame->GetTextNodeForParaProps();
1693 
1694  if( m_aFlags.bSetNumRule )
1695  {
1696  if( m_aFlags.bAFormatByInput )
1697  {
1698  m_aDelPam.SetMark();
1699  SwTextFrame const*const pNextFrame = GetNextNode(false);
1700  assert(pNextFrame);
1701  m_aDelPam.GetMark()->nNode = *pNextFrame->GetTextNodeForParaProps();
1702  m_aDelPam.GetNode(false).GetTextNode()->SetAttrListLevel( nLvl );
1703  }
1704 
1705  const_cast<SwTextNode*>(m_pCurTextFrame->GetTextNodeForParaProps())->SetAttrListLevel(nLvl);
1706 
1707  // start new list
1708  m_pDoc->SetNumRule(m_aDelPam, aRule, true, m_pEditShell->GetLayout());
1709  m_aDelPam.DeleteMark();
1710 
1711  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
1712  }
1713  else
1714  {
1715  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
1716  bChgEnum ? nTextStt : TextFrameIndex(0));
1717  }
1718  m_aDelPam.SetMark();
1719 
1720  if ( bChgBullet )
1721  nTextStt += TextFrameIndex(2);
1722 
1723  while (nTextStt < TextFrameIndex(rStr.getLength()) && IsSpace(rStr[sal_Int32(nTextStt)]))
1724  nTextStt++;
1725 
1726  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nTextStt);
1727  DeleteSel( m_aDelPam );
1728 
1729  if( !m_aFlags.bSetNumRule )
1730  {
1731  OUString sChgStr('\t');
1732  if( bChgBullet )
1733  sChgStr = OUString(&m_aFlags.cBullet, 1) + sChgStr;
1734  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, sChgStr );
1735 
1736  SfxItemSet aSet( m_pDoc->GetAttrPool(), aTextNodeSetRange );
1737  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
1738  assert(&m_aDelPam.GetPoint()->nNode.GetNode() == m_pCurTextFrame->GetTextNodeForParaProps());
1739  if( bChgBullet )
1740  {
1741  m_aDelPam.SetMark();
1742  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(1));
1743  SetAllScriptItem( aSet,
1745  m_aFlags.aBulletFont.GetFamilyName(),
1746  m_aFlags.aBulletFont.GetStyleName(),
1747  m_aFlags.aBulletFont.GetPitch(),
1748  m_aFlags.aBulletFont.GetCharSet(),
1749  RES_CHRATR_FONT ) );
1750  m_pDoc->SetFormatItemByAutoFormat( m_aDelPam, aSet );
1751  m_aDelPam.DeleteMark();
1752  nAutoCorrPos = TextFrameIndex(2);
1753  aSet.ClearItem();
1754  }
1756  aTStops.Insert( SvxTabStop( 0 ) );
1757  aSet.Put( aTStops );
1758  assert(&m_aDelPam.GetPoint()->nNode.GetNode() == m_pCurTextFrame->GetTextNodeForParaProps());
1759  m_pDoc->SetFormatItemByAutoFormat( m_aDelPam, aSet );
1760  }
1761  }
1762 
1763  if( bBreak )
1764  {
1765  AutoCorrect( nAutoCorrPos ); /* Offset due to Bullet + Tab */
1766  return;
1767  }
1768 
1769  const SwTextFrame * pNextFrame = GetNextNode();
1770  while (CanJoin(pNextFrame)
1771  && nLvl == CalcLevel(*pNextFrame))
1772  {
1774  bBreak = !IsFastFullLine(*pNextFrame)
1775  || IsBlanksInString(*pNextFrame)
1776  || IsSentenceAtEnd(*pNextFrame);
1777  if (DeleteJoinCurNextPara(pNextFrame))
1778  {
1779  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
1780  }
1781  if( bBreak )
1782  break;
1783  const SwTextFrame *const pCurrNode = pNextFrame;
1784  pNextFrame = GetNextNode();
1785  if (!pNextFrame || pCurrNode == pNextFrame)
1786  break;
1787  }
1788  DeleteLeadingTrailingBlanks( false );
1789  AutoCorrect( nAutoCorrPos );
1790 }
1791 
1793 {
1795  // Test of contraposition (n words, divided by spaces/tabs, with same indentation in 2nd line)
1796 
1797  // read all succeeding paragraphs that belong to this enumeration
1798  bool bBreak = true;
1799  TextFrameIndex nSpacePos(0);
1800  const sal_Int32 nTextPos = GetBigIndent( nSpacePos );
1801  if( m_bMoreLines )
1802  DelMoreLinesBlanks( true );
1803  else
1804  bBreak = !IsFastFullLine(*m_pCurTextFrame)
1805  || (!nTextPos && IsBlanksInString(*m_pCurTextFrame))
1806  || IsSentenceAtEnd(*m_pCurTextFrame);
1807 
1808  SetColl( o3tl::narrowing<sal_uInt16>( nTextPos
1811 
1812  if( nTextPos )
1813  {
1814  const OUString& rStr = m_pCurTextFrame->GetText();
1815  bool bInsTab = true;
1816 
1817  if ('\t' == rStr[sal_Int32(nSpacePos) + 1]) // leave tab alone
1818  {
1819  --nSpacePos;
1820  bInsTab = false;
1821  }
1822 
1823  TextFrameIndex nSpaceStt = nSpacePos;
1824  while (nSpaceStt && IsSpace(rStr[sal_Int32(--nSpaceStt)]))
1825  ;
1826  ++nSpaceStt;
1827 
1828  if (bInsTab && '\t' == rStr[sal_Int32(nSpaceStt)]) // leave tab alone
1829  {
1830  ++nSpaceStt;
1831  bInsTab = false;
1832  }
1833 
1834  m_aDelPam.DeleteMark();
1835  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nSpacePos);
1836 
1837  // delete old Spaces, etc.
1838  if( nSpaceStt < nSpacePos )
1839  {
1840  m_aDelPam.SetMark();
1841  *m_aDelPam.GetMark() = m_pCurTextFrame->MapViewToModelPos(nSpaceStt);
1842  DeleteSel( m_aDelPam );
1843  if( bInsTab )
1844  {
1845  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString('\t') );
1846  }
1847  }
1848  }
1849 
1850  if( !bBreak )
1851  {
1853  SwTextFrameInfo aFInfo( m_pCurTextFrame );
1854  const SwTextFrame * pNextFrame = GetNextNode();
1855  while (CanJoin(pNextFrame) &&
1856  20 < std::abs( static_cast<tools::Long>(nSpaces - aFInfo.SetFrame(
1857  EnsureFormatted(*pNextFrame)).GetLineStart()) )
1858  )
1859  {
1860  bBreak = !IsFastFullLine(*pNextFrame)
1861  || IsBlanksInString(*pNextFrame)
1862  || IsSentenceAtEnd(*pNextFrame);
1863  if (DeleteJoinCurNextPara(pNextFrame))
1864  {
1865  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
1866  }
1867  if( bBreak )
1868  break;
1869  pNextFrame = GetNextNode();
1870  }
1871  }
1873  AutoCorrect();
1874 }
1875 
1876 void SwAutoFormat::BuildHeadLine( sal_uInt16 nLvl )
1877 {
1878  if( m_aFlags.bWithRedlining )
1879  {
1880  OUString sText(SwViewShell::GetShellRes()->GetAutoFormatNameLst()[
1882  sText = sText.replaceAll( "$(ARG1)", OUString::number( nLvl + 1 ) );
1884  }
1885 
1886  SetColl( o3tl::narrowing<sal_uInt16>(RES_POOLCOLL_HEADLINE1 + nLvl ), true );
1887  if( m_aFlags.bAFormatByInput )
1888  {
1889  SwTextFormatColl& rNxtColl = m_pCurTextFrame->GetTextNodeForParaProps()->GetTextColl()->GetNextTextFormatColl();
1890 
1891  JoinPrevPara();
1892 
1893  DeleteLeadingTrailingBlanks( true, false );
1894  const SwTextFrame* pNextFrame = GetNextNode(false);
1895  if (pNextFrame->GetNext())
1896  {
1897  (void)DeleteJoinCurNextPara(pNextFrame, true);
1898  pNextFrame = GetNextNode(false);
1899  }
1900  m_aDelPam.DeleteMark();
1901  m_aDelPam.GetPoint()->nNode = *pNextFrame->GetTextNodeForParaProps();
1902  m_aDelPam.GetPoint()->nContent.Assign( m_aDelPam.GetContentNode(), 0 );
1903  m_pDoc->SetTextFormatColl( m_aDelPam, &rNxtColl );
1904  }
1905  else
1906  {
1908  AutoCorrect();
1909  }
1910 }
1911 
1914 {
1916  ACFlags aSvxFlags = pATst->GetFlags( );
1917  bool bReplaceQuote( aSvxFlags & ACFlags::ChgQuotes );
1918  bool bReplaceSglQuote( aSvxFlags & ACFlags::ChgSglQuotes );
1919 
1920  if( m_aFlags.bAFormatByInput ||
1921  (!m_aFlags.bAutoCorrect && !bReplaceQuote && !bReplaceSglQuote &&
1922  !m_aFlags.bCapitalStartSentence && !m_aFlags.bCapitalStartWord &&
1923  !m_aFlags.bChgOrdinalNumber && !m_aFlags.bTransliterateRTL &&
1924  !m_aFlags.bChgToEnEmDash && !m_aFlags.bSetINetAttr &&
1925  !m_aFlags.bChgWeightUnderl && !m_aFlags.bAddNonBrkSpace) )
1926  return;
1927 
1928  const OUString* pText = &m_pCurTextFrame->GetText();
1929  if (TextFrameIndex(pText->getLength()) <= nPos)
1930  return;
1931 
1932  bool bGetLanguage = m_aFlags.bChgOrdinalNumber || m_aFlags.bTransliterateRTL ||
1933  m_aFlags.bChgToEnEmDash || m_aFlags.bSetINetAttr ||
1934  m_aFlags.bCapitalStartWord || m_aFlags.bCapitalStartSentence ||
1935  m_aFlags.bAddNonBrkSpace;
1936 
1937  m_aDelPam.DeleteMark();
1938  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
1939 
1940  SwAutoCorrDoc aACorrDoc( *m_pEditShell, m_aDelPam );
1941 
1942  SwTextFrameInfo aFInfo( nullptr );
1943 
1944  TextFrameIndex nSttPos, nLastBlank = nPos;
1945  bool bFirst = m_aFlags.bCapitalStartSentence, bFirstSent = bFirst;
1946  sal_Unicode cChar = 0;
1947  bool bNbspRunNext = false;
1948 
1949  CharClass& rAppCC = GetAppCharClass();
1950 
1951  do {
1952  while (nPos < TextFrameIndex(pText->getLength())
1953  && IsSpace(cChar = (*pText)[sal_Int32(nPos)]))
1954  ++nPos;
1955  if (nPos == TextFrameIndex(pText->getLength()))
1956  break; // that's it
1957 
1958  if( ( ( bReplaceQuote && '\"' == cChar ) ||
1959  ( bReplaceSglQuote && '\'' == cChar ) ) &&
1960  (!nPos || ' ' == (*pText)[sal_Int32(nPos)-1]))
1961  {
1962 
1963  // note: special case symbol fonts !!!
1964  if( !aFInfo.GetFrame() )
1965  aFInfo.SetFrame( GetFrame( *m_pCurTextNd ) );
1966  if( !aFInfo.IsBullet( nPos ))
1967  {
1969  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
1970  bool bSetHardBlank = false;
1971 
1972  OUString sReplace( pATst->GetQuote( aACorrDoc,
1973  sal_Int32(nPos), cChar, true ));
1974 
1975  m_aDelPam.SetMark();
1976  m_aDelPam.GetPoint()->nContent = m_aDelPam.GetMark()->nContent.GetIndex() + 1;
1977  if( 2 == sReplace.getLength() && ' ' == sReplace[ 1 ])
1978  {
1979  sReplace = sReplace.copy( 0, 1 );
1980  bSetHardBlank = true;
1981  }
1982  m_pDoc->getIDocumentContentOperations().ReplaceRange( m_aDelPam, sReplace, false );
1983 
1984  if( m_aFlags.bWithRedlining )
1985  {
1986  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
1987  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
1988  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
1989  pText = &m_pCurTextFrame->GetText();
1990  m_aDelPam.SetMark();
1991  aFInfo.SetFrame( nullptr );
1992  }
1993 
1994  nPos += TextFrameIndex(sReplace.getLength() - 1);
1995  m_aDelPam.DeleteMark();
1996  if( bSetHardBlank )
1997  {
1998  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(CHAR_HARDBLANK) );
1999  ++nPos;
2000  }
2001  }
2002  }
2003 
2004  bool bCallACorr = false;
2005  int bBreak = 0;
2006  if (nPos && IsSpace((*pText)[sal_Int32(nPos) - 1]))
2007  nLastBlank = nPos;
2008  for (nSttPos = nPos; !bBreak && nPos < TextFrameIndex(pText->getLength()); ++nPos)
2009  {
2010  cChar = (*pText)[sal_Int32(nPos)];
2011  switch (cChar)
2012  {
2013  case '\"':
2014  case '\'':
2015  if( ( cChar == '\"' && bReplaceQuote ) || ( cChar == '\'' && bReplaceSglQuote ) )
2016  {
2017  // consider Symbolfonts!
2018  if( !aFInfo.GetFrame() )
2019  aFInfo.SetFrame( GetFrame( *m_pCurTextNd ) );
2020  if( !aFInfo.IsBullet( nPos ))
2021  {
2023  bool bSetHardBlank = false;
2024  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
2025  OUString sReplace( pATst->GetQuote( aACorrDoc,
2026  sal_Int32(nPos), cChar, false) );
2027 
2028  if( 2 == sReplace.getLength() && ' ' == sReplace[ 0 ])
2029  {
2030  sReplace = sReplace.copy( 1 );
2031  bSetHardBlank = true;
2032  }
2033 
2034  m_aDelPam.SetMark();
2035  m_aDelPam.GetPoint()->nContent = m_aDelPam.GetMark()->nContent.GetIndex() + 1;
2036  m_pDoc->getIDocumentContentOperations().ReplaceRange( m_aDelPam, sReplace, false );
2037 
2038  if( m_aFlags.bWithRedlining )
2039  {
2040  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
2041  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
2042  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
2043  pText = &m_pCurTextFrame->GetText();
2044  m_aDelPam.SetMark();
2045  m_aDelPam.DeleteMark();
2046  aFInfo.SetFrame( nullptr );
2047  }
2048 
2049  nPos += TextFrameIndex(sReplace.getLength() - 1);
2050  m_aDelPam.DeleteMark();
2051 
2052  if( bSetHardBlank )
2053  {
2054  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
2055  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(CHAR_HARDBLANK) );
2056  ++nPos;
2057  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
2058  }
2059  }
2060  }
2061  break;
2062  case '*':
2063  case '_':
2064  if( m_aFlags.bChgWeightUnderl )
2065  {
2066  // consider Symbolfonts!
2067  if( !aFInfo.GetFrame() )
2068  aFInfo.SetFrame( GetFrame( *m_pCurTextNd ) );
2069  if( !aFInfo.IsBullet( nPos ))
2070  {
2071  SetRedlineText( '*' == cChar
2074 
2075  sal_Unicode cBlank = nSttPos ? (*pText)[sal_Int32(nSttPos) - 1] : 0;
2076  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
2077 
2078  if (pATst->FnChgWeightUnderl(aACorrDoc, *pText, sal_Int32(nPos)))
2079  {
2080  if( m_aFlags.bWithRedlining )
2081  {
2082  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
2083  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
2084  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
2085  pText = &m_pCurTextFrame->GetText();
2086  m_aDelPam.SetMark();
2087  m_aDelPam.DeleteMark();
2088  aFInfo.SetFrame( nullptr );
2089  }
2090  //#125102# in case of the mode RedlineFlags::ShowDelete the ** are still contained in pText
2092  nPos = m_pCurTextFrame->MapModelToViewPos(*m_aDelPam.GetPoint()) - TextFrameIndex(1);
2093  // Was a character deleted before starting?
2094  if (cBlank && cBlank != (*pText)[sal_Int32(nSttPos) - 1])
2095  --nSttPos;
2096  }
2097  }
2098  }
2099  break;
2100  case '/':
2101  if ( m_aFlags.bAddNonBrkSpace )
2102  {
2103  LanguageType eLang = bGetLanguage
2104  ? m_pCurTextFrame->GetLangOfChar(nSttPos, 0, true)
2105  : LANGUAGE_SYSTEM;
2106 
2108  if (pATst->FnAddNonBrkSpace(aACorrDoc, *pText, sal_Int32(nPos), eLang, bNbspRunNext))
2109  --nPos;
2110  }
2111  break;
2112 
2113  case '.':
2114  case '!':
2115  case '?':
2116  if( m_aFlags.bCapitalStartSentence )
2117  bFirstSent = true;
2118  [[fallthrough]];
2119  default:
2120  if (!(rAppCC.isLetterNumeric(*pText, sal_Int32(nPos))
2121  || '/' == cChar )) // '/' should not be a word separator (e.g. '1/2' needs to be handled as one word for replacement)
2122  {
2123  --nPos; // revert ++nPos which was decremented in for loop
2124  ++bBreak;
2125  }
2126  break;
2127  }
2128  }
2129 
2130  if( nPos == nSttPos )
2131  {
2132  if (++nPos == TextFrameIndex(pText->getLength()))
2133  bCallACorr = true;
2134  }
2135  else
2136  bCallACorr = true;
2137 
2138  if( bCallACorr )
2139  {
2140  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
2142 
2143  LanguageType eLang = bGetLanguage
2144  ? m_pCurTextFrame->GetLangOfChar(nSttPos, 0, true)
2145  : LANGUAGE_SYSTEM;
2146 
2147  if( m_bIsRightToLeft && m_aFlags.bTransliterateRTL && eLang == LANGUAGE_HUNGARIAN &&
2149  aACorrDoc.TransliterateRTLWord(reinterpret_cast<sal_Int32&>(nSttPos), sal_Int32(nPos), /*bApply=*/true))
2150  {
2151  nPos = m_pCurTextFrame->MapModelToViewPos(*m_aDelPam.GetPoint());
2152 
2153  if( m_aFlags.bWithRedlining )
2154  {
2155  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
2156  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
2157  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
2158  pText = &m_pCurTextFrame->GetText();
2159  m_aDelPam.SetMark();
2160  m_aDelPam.DeleteMark();
2161  }
2162 
2163  continue; // do not check further
2164  }
2165 
2166  if( m_aFlags.bAutoCorrect &&
2167  aACorrDoc.ChgAutoCorrWord(reinterpret_cast<sal_Int32&>(nSttPos), sal_Int32(nPos), *pATst, nullptr) )
2168  {
2169  nPos = m_pCurTextFrame->MapModelToViewPos(*m_aDelPam.GetPoint());
2170  if( m_aFlags.bWithRedlining )
2171  {
2172  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
2173  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
2174  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
2175  pText = &m_pCurTextFrame->GetText();
2176  m_aDelPam.SetMark();
2177  m_aDelPam.DeleteMark();
2178  }
2179 
2180  continue; // do not check further
2181  }
2182 
2183  if ( m_aFlags.bAddNonBrkSpace && nPos < TextFrameIndex(pText->getLength()) )
2184  {
2186  pATst->FnAddNonBrkSpace(aACorrDoc, *pText, sal_Int32(nPos), eLang, bNbspRunNext);
2187  }
2188 
2189  if( ( m_aFlags.bChgOrdinalNumber &&
2191  pATst->FnChgOrdinalNumber(aACorrDoc, *pText, sal_Int32(nSttPos), sal_Int32(nPos), eLang)) ||
2192  ( m_aFlags.bChgToEnEmDash &&
2194  pATst->FnChgToEnEmDash(aACorrDoc, *pText, sal_Int32(nSttPos), sal_Int32(nPos), eLang)) ||
2195  ( m_aFlags.bSetINetAttr &&
2196  (nPos == TextFrameIndex(pText->getLength()) || IsSpace((*pText)[sal_Int32(nPos)])) &&
2198  pATst->FnSetINetAttr(aACorrDoc, *pText, sal_Int32(nLastBlank), sal_Int32(nPos), eLang)))
2199  {
2200  nPos = m_pCurTextFrame->MapModelToViewPos(*m_aDelPam.GetPoint());
2201  }
2202  else
2203  {
2204  // two capital letters at the beginning of a word?
2205  if( m_aFlags.bCapitalStartWord )
2206  {
2208  pATst->FnCapitalStartWord(aACorrDoc, *pText, sal_Int32(nSttPos), sal_Int32(nPos), eLang);
2209  }
2210  // capital letter at the beginning of a sentence?
2211  if( m_aFlags.bCapitalStartSentence && bFirst )
2212  {
2214  pATst->FnCapitalStartSentence(aACorrDoc, *pText, true, sal_Int32(nSttPos), sal_Int32(nPos), eLang);
2215  }
2216 
2217  bFirst = bFirstSent;
2218  bFirstSent = false;
2219 
2220  if( m_aFlags.bWithRedlining )
2221  {
2222  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
2223  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
2224  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
2225  pText = &m_pCurTextFrame->GetText();
2226  m_aDelPam.SetMark();
2227  m_aDelPam.DeleteMark();
2228  }
2229  }
2230  }
2231  }
2232  while (nPos < TextFrameIndex(pText->getLength()));
2233  ClearRedlineText();
2234 }
2235 
2237  SwNodeIndex const * pSttNd, SwNodeIndex const * pEndNd )
2238  : m_aFlags( rFlags ),
2239  m_aDelPam( pEdShell->GetDoc()->GetNodes().GetEndOfExtras() ),
2240  m_aNdIdx( pEdShell->GetDoc()->GetNodes().GetEndOfExtras(), SwNodeOffset(+1) ),
2241  m_aEndNdIdx( pEdShell->GetDoc()->GetNodes().GetEndOfContent() ),
2242  m_pEditShell( pEdShell ),
2243  m_pDoc( pEdShell->GetDoc() ),
2244  m_pCurTextNd( nullptr ), m_pCurTextFrame( nullptr ),
2245  m_nRedlAutoFormatSeqId( 0 )
2246 {
2247  OSL_ENSURE( (pSttNd && pEndNd) || (!pSttNd && !pEndNd),
2248  "Got no area" );
2249 
2250  if( m_aFlags.bSetNumRule && !m_aFlags.bAFormatByInput )
2251  m_aFlags.bSetNumRule = false;
2252 
2253  bool bReplaceStyles = !m_aFlags.bAFormatByInput || m_aFlags.bReplaceStyles;
2254 
2255  const SwTextFrame * pNextFrame = nullptr;
2256  bool bNxtEmpty = false;
2257  bool bNxtAlpha = false;
2258  sal_uInt16 nNxtLevel = 0;
2259  bool bEmptyLine;
2260 
2261  // set area for autoformatting
2262  if( pSttNd )
2263  {
2264  m_aNdIdx = *pSttNd;
2265  // for GoNextPara, one paragraph prior to that
2266  sw::GotoPrevLayoutTextFrame(m_aNdIdx, m_pEditShell->GetLayout());
2267  m_aEndNdIdx = *pEndNd;
2268  sw::GotoNextLayoutTextFrame(m_aEndNdIdx, m_pEditShell->GetLayout());
2269 
2270  // check the previous TextNode
2271  SwTextFrame const*const pPrevFrame = m_aNdIdx.GetNode().GetTextNode()
2272  ? static_cast<SwTextFrame const*>(m_aNdIdx.GetNode().GetTextNode()->getLayoutFrame(m_pEditShell->GetLayout()))
2273  : nullptr;
2274  bEmptyLine = !pPrevFrame
2275  || IsEmptyLine(*pPrevFrame)
2276  || IsNoAlphaLine(*pPrevFrame);
2277  }
2278  else
2279  bEmptyLine = true; // at document beginning
2280 
2281  m_bEnd = false;
2282 
2283  // set value for percentage display
2284  m_nEndNdIdx = m_aEndNdIdx.GetIndex();
2285 
2286  if( !m_aFlags.bAFormatByInput )
2287  {
2288  m_nEndNdIdx = m_aEndNdIdx.GetIndex();
2289  ::StartProgress( STR_STATSTR_AUTOFORMAT, sal_Int32(m_aNdIdx.GetIndex()),
2290  sal_Int32(m_nEndNdIdx),
2291  m_pDoc->GetDocShell() );
2292  }
2293 
2294  RedlineFlags eRedlMode = m_pDoc->getIDocumentRedlineAccess().GetRedlineFlags(), eOldMode = eRedlMode;
2295  if( m_aFlags.bWithRedlining )
2296  {
2297  m_pDoc->SetAutoFormatRedline( true );
2298  eRedlMode = RedlineFlags::On | (eOldMode & RedlineFlags::ShowMask);
2299  }
2300  else
2301  eRedlMode = RedlineFlags::Ignore | (eOldMode & RedlineFlags::ShowMask);
2302  m_pDoc->getIDocumentRedlineAccess().SetRedlineFlags( eRedlMode );
2303 
2304  // save undo state (might be turned off)
2305  bool const bUndoState = m_pDoc->GetIDocumentUndoRedo().DoesUndo();
2306 
2307  // If multiple lines, then do not merge with next paragraph
2308  m_bMoreLines = false;
2309 
2310  sal_uInt16 nLastCalcHeadLvl = 0;
2311  sal_uInt16 nLastHeadLvl = USHRT_MAX;
2312  sal_uInt16 nLevel = 0;
2313  sal_uInt16 nDigitLvl = 0;
2314 
2315  // set defaults
2316  SwTextFrameInfo aFInfo( nullptr );
2317 
2318  enum Format_Status
2319  {
2320  READ_NEXT_PARA, // -> ISEND, TST_EMPTY_LINE
2321  TST_EMPTY_LINE, // -> READ_NEXT_PARA, TST_ALPHA_LINE
2322  TST_ALPHA_LINE, // -> READ_NEXT_PARA, GET_ALL_INFO, IS_END
2323  GET_ALL_INFO, // -> READ_NEXT_PARA, IS_ONE_LINE, TST_ENUMERIC, HAS_FMTCOLL
2324  IS_ONE_LINE, // -> READ_NEXT_PARA, TST_ENUMERIC
2325  TST_ENUMERIC, // -> READ_NEXT_PARA, TST_IDENT, TST_NEG_IDENT
2326  TST_IDENT, // -> READ_NEXT_PARA, TST_TXT_BODY
2327  TST_NEG_IDENT, // -> READ_NEXT_PARA, TST_TXT_BODY
2328  TST_TXT_BODY, // -> READ_NEXT_PARA
2329  HAS_FMTCOLL, // -> READ_NEXT_PARA
2330  IS_END
2331  } eStat;
2332 
2333  // This is the automat for autoformatting
2334  eStat = READ_NEXT_PARA;
2335  while( !m_bEnd )
2336  {
2337  switch( eStat )
2338  {
2339  case READ_NEXT_PARA:
2340  {
2341  GoNextPara();
2342  eStat = m_bEnd ? IS_END : TST_EMPTY_LINE;
2343  }
2344  break;
2345 
2346  case TST_EMPTY_LINE:
2347  if (IsEmptyLine(*m_pCurTextFrame))
2348  {
2349  if (m_aFlags.bDelEmptyNode && !HasObjects(*m_pCurTextFrame))
2350  {
2351  bEmptyLine = true;
2352  SwNodeOffset nOldCnt = m_pDoc->GetNodes().Count();
2353  DelEmptyLine();
2354  // Was there really a deletion of a node?
2355  if( nOldCnt != m_pDoc->GetNodes().Count() )
2356  {
2357  // do not skip the next paragraph
2358  sw::GotoPrevLayoutTextFrame(m_aNdIdx, m_pEditShell->GetLayout());
2359  }
2360  }
2361  eStat = READ_NEXT_PARA;
2362  }
2363  else
2364  eStat = TST_ALPHA_LINE;
2365  break;
2366 
2367  case TST_ALPHA_LINE:
2368  if (IsNoAlphaLine(*m_pCurTextFrame))
2369  {
2370  // recognize a table definition +---+---+
2371  if( m_aFlags.bAFormatByInput && m_aFlags.bCreateTable && DoTable() )
2372  {
2373  //JP 30.09.96: DoTable() builds on PopCursor and MoveCursor after AutoFormat!
2375  static_cast<SwPaM&>(*pEdShell->GetCursor()) = m_aDelPam;
2376  pEdShell->Push();
2377 
2378  eStat = IS_END;
2379  break;
2380  }
2381 
2382  // Check for 3 "---" or "===". In this case, the previous paragraph should be
2383  // underlined and the current be deleted!
2384  if( !DoUnderline() && bReplaceStyles )
2385  {
2386  SetColl( RES_POOLCOLL_STANDARD, true );
2387  bEmptyLine = true;
2388  }
2389  eStat = READ_NEXT_PARA;
2390  }
2391  else
2392  eStat = GET_ALL_INFO;
2393  break;
2394 
2395  case GET_ALL_INFO:
2396  {
2397  if (m_pCurTextFrame->GetTextNodeForParaProps()->GetNumRule())
2398  {
2399  // do nothing in numbering, go to next
2400  bEmptyLine = false;
2401  eStat = READ_NEXT_PARA;
2402  // delete all blanks at beginning/end and in between
2403  //JP 29.04.98: first only "all in between"
2405  break;
2406  }
2407 
2408  aFInfo.SetFrame( m_pCurTextFrame );
2409 
2410  // so far: if there were templates assigned, keep these and go to next node
2411  sal_uInt16 nPoolId = m_pCurTextFrame->GetTextNodeForParaProps()->GetTextColl()->GetPoolFormatId();
2412  if( IsPoolUserFormat( nPoolId )
2413  ? !m_aFlags.bChgUserColl
2414  : ( RES_POOLCOLL_STANDARD != nPoolId &&
2415  ( !m_aFlags.bAFormatByInput ||
2416  (RES_POOLCOLL_TEXT_MOVE != nPoolId &&
2417  RES_POOLCOLL_TEXT != nPoolId )) ))
2418  {
2419  eStat = HAS_FMTCOLL;
2420  break;
2421  }
2422 
2423  // check for hard spaces or LRSpaces set by the template
2424  if( IsPoolUserFormat( nPoolId ) ||
2425  RES_POOLCOLL_STANDARD == nPoolId )
2426  {
2427  short nSz;
2428  SvxLRSpaceItem const * pLRSpace = m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().
2429  GetItemIfSet( RES_LR_SPACE );
2430  if (pLRSpace &&
2431  ( 0 != (nSz = pLRSpace->GetTextFirstLineOffset()) ||
2432  0 != pLRSpace->GetTextLeft() ) )
2433  {
2434  // exception: numbering/enumeration can have an indentation
2435  if (IsEnumericChar(*m_pCurTextFrame))
2436  {
2437  nLevel = CalcLevel(*m_pCurTextFrame, &nDigitLvl);
2438  if( nLevel >= MAXLEVEL )
2439  nLevel = MAXLEVEL-1;
2440  BuildEnum( nLevel, nDigitLvl );
2441  eStat = READ_NEXT_PARA;
2442  break;
2443  }
2444 
2445  // never merge (maybe only indent as exception)
2446  m_bMoreLines = true;
2447 
2448  if( bReplaceStyles )
2449  {
2450  // then use one of our templates
2451  if( 0 < nSz ) // positive 1st line indentation
2452  BuildIndent();
2453  else if( 0 > nSz ) // negative 1st line indentation
2454  BuildNegIndent( aFInfo.GetLineStart() );
2455  else if( pLRSpace->GetTextLeft() ) // is indentation
2456  BuildTextIndent();
2457  }
2458  eStat = READ_NEXT_PARA;
2459  break;
2460  }
2461  }
2462 
2463  nLevel = CalcLevel( *m_pCurTextFrame, &nDigitLvl );
2464  m_bMoreLines = !IsOneLine(*m_pCurTextFrame);
2465  // note: every use of pNextFrame in following states, until the
2466  // next READ_NEXT_PARA, relies on this update
2467  pNextFrame = GetNextNode();
2468  if (pNextFrame)
2469  {
2470  bNxtEmpty = IsEmptyLine(*pNextFrame);
2471  bNxtAlpha = IsNoAlphaLine(*pNextFrame);
2472  nNxtLevel = CalcLevel(*pNextFrame);
2473 
2474  if (!bEmptyLine && HasBreakAttr(*m_pCurTextFrame))
2475  bEmptyLine = true;
2476  if (!bNxtEmpty && HasBreakAttr(*pNextFrame))
2477  bNxtEmpty = true;
2478 
2479  }
2480  else
2481  {
2482  bNxtEmpty = false;
2483  bNxtAlpha = false;
2484  nNxtLevel = 0;
2485  }
2486  eStat = !m_bMoreLines ? IS_ONE_LINE : TST_ENUMERIC;
2487  }
2488  break;
2489 
2490  case IS_ONE_LINE:
2491  {
2492  eStat = TST_ENUMERIC;
2493  if( !bReplaceStyles )
2494  break;
2495 
2496  const OUString sClrStr( DelLeadingBlanks(m_pCurTextFrame->GetText()) );
2497 
2498  if( sClrStr.isEmpty() )
2499  {
2500  bEmptyLine = true;
2501  eStat = READ_NEXT_PARA;
2502  break; // read next paragraph
2503  }
2504 
2505  // check if headline
2506  if (!bEmptyLine || !IsFirstCharCapital(*m_pCurTextFrame)
2507  || IsBlanksInString(*m_pCurTextFrame))
2508  break;
2509 
2510  bEmptyLine = false;
2511  const OUString sEndClrStr( DelTrailingBlanks(sClrStr) );
2512  const sal_Unicode cLast = sEndClrStr[sEndClrStr.getLength() - 1];
2513 
2514  // not, then check if headline
2515  if( ':' == cLast )
2516  {
2517  BuildHeadLine( 2 );
2518  eStat = READ_NEXT_PARA;
2519  break;
2520  }
2521  else if( 256 <= cLast || !strchr( ",.;", cLast ) )
2522  {
2523  if( bNxtEmpty || bNxtAlpha
2524  || (pNextFrame && IsEnumericChar(*pNextFrame)))
2525  {
2526 
2527  // one level below?
2528  if( nLevel >= MAXLEVEL )
2529  nLevel = MAXLEVEL-1;
2530 
2531  if( USHRT_MAX == nLastHeadLvl )
2532  nLastHeadLvl = 0;
2533  else if( nLastCalcHeadLvl < nLevel )
2534  {
2535  if( nLastHeadLvl+1 < MAXLEVEL )
2536  ++nLastHeadLvl;
2537  }
2538  // one level above?
2539  else if( nLastCalcHeadLvl > nLevel )
2540  {
2541  if( nLastHeadLvl )
2542  --nLastHeadLvl;
2543  }
2544  nLastCalcHeadLvl = nLevel;
2545 
2546  if( m_aFlags.bAFormatByInput )
2547  BuildHeadLine( nLevel );
2548  else
2549  BuildHeadLine( nLastHeadLvl );
2550  eStat = READ_NEXT_PARA;
2551  break;
2552  }
2553  }
2554  }
2555  break;
2556 
2557  case TST_ENUMERIC:
2558  {
2559  bEmptyLine = false;
2560  if (IsEnumericChar(*m_pCurTextFrame))
2561  {
2562  if( nLevel >= MAXLEVEL )
2563  nLevel = MAXLEVEL-1;
2564  BuildEnum( nLevel, nDigitLvl );
2565  eStat = READ_NEXT_PARA;
2566  }
2567  else if( bReplaceStyles )
2568  eStat = nLevel ? TST_IDENT : TST_NEG_IDENT;
2569  else
2570  eStat = READ_NEXT_PARA;
2571  }
2572  break;
2573 
2574  case TST_IDENT:
2575  // Spaces at the beginning, check again for indentation
2576  if( m_bMoreLines && nLevel )
2577  {
2578  SwTwips nSz = aFInfo.GetFirstIndent();
2579  if( 0 < nSz ) // positive 1st line indentation
2580  BuildIndent();
2581  else if( 0 > nSz ) // negative 1st line indentation
2582  BuildNegIndent( aFInfo.GetLineStart() );
2583  else // is indentation
2584  BuildTextIndent();
2585  eStat = READ_NEXT_PARA;
2586  }
2587  else if (nLevel && pNextFrame &&
2588  !bNxtEmpty && !bNxtAlpha && !nNxtLevel &&
2589  !IsEnumericChar(*pNextFrame))
2590  {
2591  // is an indentation
2592  BuildIndent();
2593  eStat = READ_NEXT_PARA;
2594  }
2595  else
2596  eStat = TST_TXT_BODY;
2597  break;
2598 
2599  case TST_NEG_IDENT:
2600  // no spaces at the beginning, check again for negative indentation
2601  {
2602  if( m_bMoreLines && !nLevel )
2603  {
2604  SwTwips nSz = aFInfo.GetFirstIndent();
2605  if( 0 < nSz ) // positive 1st line indentation
2606  BuildIndent();
2607  else if( 0 > nSz ) // negative 1st line indentation
2608  BuildNegIndent( aFInfo.GetLineStart() );
2609  else // is _no_ indentation
2610  BuildText();
2611  eStat = READ_NEXT_PARA;
2612  }
2613  else if (!nLevel && pNextFrame &&
2614  !bNxtEmpty && !bNxtAlpha && nNxtLevel &&
2615  !IsEnumericChar(*pNextFrame))
2616  {
2617  // is a negative indentation
2618  BuildNegIndent( aFInfo.GetLineStart() );
2619  eStat = READ_NEXT_PARA;
2620  }
2621  else
2622  eStat = TST_TXT_BODY;
2623  }
2624  break;
2625 
2626  case TST_TXT_BODY:
2627  {
2628  if( m_bMoreLines )
2629  {
2630  SwTwips nSz = aFInfo.GetFirstIndent();
2631  if( 0 < nSz ) // positive 1st line indentation
2632  BuildIndent();
2633  else if( 0 > nSz ) // negative 1st line indentation
2634  BuildNegIndent( aFInfo.GetLineStart() );
2635  else if( nLevel ) // is indentation
2636  BuildTextIndent();
2637  else
2638  BuildText();
2639  }
2640  else if( nLevel )
2641  BuildTextIndent();
2642  else
2643  BuildText();
2644  eStat = READ_NEXT_PARA;
2645  }
2646  break;
2647 
2648  case HAS_FMTCOLL:
2649  {
2650  // so far: if there were templates assigned, keep these and go to next node
2651  bEmptyLine = false;
2652  eStat = READ_NEXT_PARA;
2653  // delete all blanks at beginning/end and in between
2654  //JP 29.04.98: first only "all in between"
2656 
2657  // handle hard attributes
2658  if (m_pCurTextFrame->GetTextNodeForParaProps()->HasSwAttrSet())
2659  {
2660  short nSz;
2661  SvxLRSpaceItem const * pLRSpace;
2662  if( bReplaceStyles &&
2663  (pLRSpace = m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().
2664  GetItemIfSet( RES_LR_SPACE, false )) &&
2665  ( 0 != (nSz = pLRSpace->GetTextFirstLineOffset()) ||
2666  0 != pLRSpace->GetTextLeft() ) )
2667  {
2668  // then use one of our templates
2669  if( 0 < nSz ) // positive 1st line indentation
2670  BuildIndent();
2671  else if( 0 > nSz ) // negative 1st line indentation
2672  {
2673  BuildNegIndent( aFInfo.GetLineStart() );
2674  }
2675  else if( pLRSpace->GetTextLeft() ) // is indentation
2676  BuildTextIndent();
2677  else
2678  BuildText();
2679  }
2680  }
2681  }
2682  break;
2683 
2684  case IS_END:
2685  m_bEnd = true;
2686  break;
2687  }
2688  }
2689 
2690  if( m_aFlags.bWithRedlining )
2691  m_pDoc->SetAutoFormatRedline( false );
2692  m_pDoc->getIDocumentRedlineAccess().SetRedlineFlags( eOldMode );
2693 
2694  // restore undo (in case it has been changed)
2695  m_pDoc->GetIDocumentUndoRedo().DoUndo(bUndoState);
2696 
2697  // disable display of percentage again
2698  if( !m_aFlags.bAFormatByInput )
2699  ::EndProgress( m_pDoc->GetDocShell() );
2700 }
2701 
2703 {
2704  std::unique_ptr<SwWait> pWait;
2705 
2706  CurrShell aCurr( this );
2707  StartAllAction();
2709 
2710  SvxSwAutoFormatFlags aAFFlags; // use default values or add params?
2711  if( pAFlags )
2712  {
2713  aAFFlags = *pAFlags;
2714  if( !aAFFlags.bAFormatByInput )
2715  pWait.reset(new SwWait( *GetDoc()->GetDocShell(), true ));
2716  }
2717 
2718  SwPaM* pCursor = GetCursor();
2719  // There are more than one or a selection is open
2720  if( pCursor->GetNext() != pCursor || pCursor->HasMark() )
2721  {
2722  for(SwPaM& rPaM : GetCursor()->GetRingContainer())
2723  {
2724  if( rPaM.HasMark() )
2725  {
2726  SwAutoFormat aFormat( this, aAFFlags, &(rPaM.Start()->nNode),
2727  &(rPaM.End()->nNode) );
2728  }
2729  }
2730  }
2731  else
2732  {
2733  SwAutoFormat aFormat( this, aAFFlags );
2734  }
2735 
2737  EndAllAction();
2738 }
2739 
2741 {
2742  CurrShell aCurr( this );
2743  SwPaM* pCursor = GetCursor();
2744  if( pCursor->IsMultiSelection() || !pCursor->Move( fnMoveBackward, GoInNode ) )
2745  return;
2746 
2747  StartAllAction();
2749 
2750  bool bRange = false;
2751  pCursor->SetMark();
2752  SwIndex* pContent = &pCursor->GetMark()->nContent;
2753  if( pContent->GetIndex() )
2754  {
2755  *pContent = 0;
2756  bRange = true;
2757  }
2758  else
2759  {
2760  // then go one node backwards
2761  SwNodeIndex aNdIdx(pCursor->GetMark()->nNode);
2763  SwTextNode* pTextNd = aNdIdx.GetNode().GetTextNode();
2764  if (pTextNd && !pTextNd->GetText().isEmpty())
2765  {
2766  pContent->Assign( pTextNd, 0 );
2767  pCursor->GetMark()->nNode = aNdIdx;
2768  bRange = true;
2769  }
2770  }
2771 
2772  if( bRange )
2773  {
2774  Push(); // save cursor
2775 
2776  SvxSwAutoFormatFlags aAFFlags = *GetAutoFormatFlags(); // use default values so far
2777 
2778  SwAutoFormat aFormat( this, aAFFlags, &pCursor->GetMark()->nNode,
2779  &pCursor->GetPoint()->nNode );
2781  if( pACorr && !pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord |
2782  ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL |
2783  ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | ACFlags::Autocorrect ))
2784  pACorr = nullptr;
2785 
2786  if( pACorr )
2787  AutoCorrect( *pACorr,false, u'\0' );
2788 
2789  //JP 30.09.96: DoTable() builds on PopCursor and MoveCursor!
2791  pCursor = GetCursor();
2792  }
2793  pCursor->DeleteMark();
2794  pCursor->Move( fnMoveForward, GoInNode );
2795 
2797  EndAllAction();
2798 
2799 }
2800 
2802 {
2803  if (!s_pAutoFormatFlags)
2805 
2806  return s_pAutoFormatFlags;
2807 }
2808 
2810 {
2811  SvxSwAutoFormatFlags* pEditFlags = GetAutoFormatFlags();
2812 
2813  pEditFlags->bSetNumRule = pFlags->bSetNumRule;
2814  pEditFlags->bChgEnumNum = pFlags->bChgEnumNum;
2815  pEditFlags->bSetBorder = pFlags->bSetBorder;
2816  pEditFlags->bCreateTable = pFlags->bCreateTable;
2817  pEditFlags->bReplaceStyles = pFlags->bReplaceStyles;
2818  pEditFlags->bAFormatByInpDelSpacesAtSttEnd =
2822 
2823  //JP 15.12.98: copy BulletChar and Font into "normal" ones
2824  // because AutoFormat can only work with the latter!
2825  pEditFlags->cBullet = pFlags->cByInputBullet;
2826  pEditFlags->aBulletFont = pFlags->aByInputBulletFont;
2827  pEditFlags->cByInputBullet = pFlags->cByInputBullet;
2828  pEditFlags->aByInputBulletFont = pFlags->aByInputBulletFont;
2829 }
2830 
2831 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual SwCharFormat * GetCharFormatFromPool(sal_uInt16 nId)=0
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:339
static SwTwips GetLineStart(const SwTextCursor &rLine)
Definition: frminf.cxx:87
void AutoCorrect(TextFrameIndex nSttPos=TextFrameIndex(0))
execute AutoCorrect on current TextNode
Definition: autofmt.cxx:1913
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:692
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
void merge(RingContainer< value_type > aDestRing)
Merges two ring containers.
Definition: ring.hxx:182
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:162
std::shared_ptr< SwUnoCursor > CreateUnoCursor(const SwPosition &rPos, bool bTableCursor=false)
Definition: doc.cxx:1775
constexpr TypedWhichId< SwFormatPageDesc > RES_PAGEDESC(93)
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:44
void DeleteMark()
Definition: pam.hxx:178
void SetBorderLineStyle(SvxBorderLineStyle nNew)
bool Insert(const SvxTabStop &rTab)
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:224
bool bAFormatByInpDelSpacesBetweenLines
sal_Int32 getCharacterType(const OUString &rStr, sal_Int32 nPos) const
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
void SetWidth(tools::Long nWidth)
static OUString DelTrailingBlanks(const OUString &rStr)
Definition: autofmt.cxx:697
static SvxAutoCorrCfg & Get()
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
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
constexpr TypedWhichId< SvxTabStopItem > RES_PARATR_TABSTOP(68)
bool isAlpha(const OUString &rStr, sal_Int32 nPos) const
bool IsSectionNode() const
Definition: node.hxx:654
const OUString & GetFamilyName() const
bool IsMultiSelection() const
Definition: pam.hxx:273
void DelEmptyLine(bool bTstNextPara=true)
Definition: autofmt.cxx:1240
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
SvxAdjust GetAdjust() const
LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, bool bNoChar=false) const
Definition: txtfrm.cxx:1346
sal_uInt32 sal_UCS4
SwPageDesc * GetPageDesc()
Definition: fmtpdsc.hxx:61
bool FnChgToEnEmDash(SvxAutoCorrDoc &, std::u16string_view, sal_Int32 nSttPos, sal_Int32 nEndPos, LanguageType eLang)
bool m_bIsRightToLeft
Definition: autofmt.cxx:98
#define STR_AUTOFMTREDL_NON_BREAK_SPACE
Definition: comcore.hxx:44
const OUString & GetText() const
Definition: ndtxt.hxx:218
static ShellResource * GetShellRes()
Definition: viewsh.cxx:2662
void SetColl(sal_uInt16 nId, bool bHdLineOrText=false)
Definition: autofmt.cxx:999
SwDocShell * GetDocShell()
Definition: doc.hxx:1351
static bool isLetterType(sal_Int32 nType)
const OUString & GetStyleName() const
sal_uInt16 CalcLevel(const SwTextFrame &, sal_uInt16 *pDigitLvl=nullptr) const
Definition: autofmt.cxx:432
bool FnChgOrdinalNumber(SvxAutoCorrDoc &, const OUString &, sal_Int32 nSttPos, sal_Int32 nEndPos, LanguageType eLang)
void BuildTextIndent()
Definition: autofmt.cxx:1386
SwNodeIndex nNode
Definition: pam.hxx:38
void SetCompletePaint() const
Definition: frame.hxx:994
virtual void InsertItemSet(const SwPaM &rRg, const SfxItemSet &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr)=0
SvxBreak GetBreak() const
void ClearRedlineText()
Definition: autofmt.cxx:215
bool FrameContainsNode(SwContentFrame const &rFrame, SwNodeOffset nNodeIndex)
Definition: txtfrm.cxx:290
SAL_DLLPRIVATE void DeleteSel(SwPaM &rPam, bool *pUndo=nullptr)
Definition: eddel.cxx:34
sal_uIntPtr sal_uLong
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
const SwPosition * GetMark() const
Definition: pam.hxx:210
void SetPrefix(const OUString &rSet)
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:390
SVX_NUM_CHARS_UPPER_LETTER
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:454
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
helper class to disable creation of an action by a callback event in particular, change event from a ...
Definition: rootfrm.hxx:450
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:92
void AutoCorrect(SvxAutoCorrect &rACorr, bool bInsertMode, sal_Unicode cChar)
Call AutoCorrect.
Definition: edws.cxx:255
bool IsNoAlphaLine(const SwTextFrame &) const
Definition: autofmt.cxx:500
#define CHAR_HARDBLANK
Definition: swtypes.hxx:161
bool IsPoolUserFormat(sal_uInt16 nId)
Definition: poolfmt.hxx:86
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
void DeleteSel(SwPaM &rPam)
Definition: autofmt.cxx:1159
constexpr TypedWhichId< SvxFormatBreakItem > RES_BREAK(94)
static bool HasObjects(const SwTextFrame &)
Definition: autofmt.cxx:344
::sw::DocumentRedlineManager const & GetDocumentRedlineManager() const
Definition: doc.cxx:345
SwDoc * m_pDoc
Definition: autofmt.cxx:95
SwNode & GetNode() const
Definition: ndindex.hxx:128
static bool HasSelBlanks(SwTextFrame const *const pStartFrame, TextFrameIndex &rStartIndex, SwTextFrame const *const pEndFrame, TextFrameIndex &rEndIndex)
Definition: autofmt.cxx:1029
void EndProgress(SwDocShell const *pDocShell)
Definition: mainwn.cxx:92
OUString GetUniqueNumRuleName(const OUString *pChkStr=nullptr, bool bAutoNum=true) const
Definition: docnum.cxx:2551
Dialog to specify the properties of date form field.
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:144
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1788
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
void SetIncludeUpperLevels(sal_uInt8 nSet)
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1296
SwNodeOffset abs(const SwNodeOffset &a)
Definition: nodeoffset.hxx:34
void StartProgress(TranslateId pMessResId, tools::Long nStartValue, tools::Long nEndValue, SwDocShell *pDocShell)
Definition: mainwn.cxx:52
SwTextFrame * EnsureFormatted(SwTextFrame const &) const
Definition: autofmt.cxx:240
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
sal_Int32 GetBigIndent(TextFrameIndex &rFndPos, const SwTextFrame *pNextFrame) const
Definition: frminf.cxx:237
void EndAllAction()
Definition: edws.cxx:97
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_FONT(7)
static sal_Int32 GetLeadingBlanks(const OUString &rStr)
Definition: autofmt.cxx:710
void MoveTo(value_type *pDestRing)
Removes this item from its current ring container and adds it to another ring container.
Definition: ring.hxx:135
UseOnPage GetUseOn() const
Definition: pagedesc.hxx:353
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:171
#define LANGUAGE_HUNGARIAN
FontFamily GetFamilyType()
const SwSection & GetSection() const
Definition: node.hxx:549
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:230
bool bAFormatByInpDelSpacesAtSttEnd
const sal_Unicode cStarSymbolEmDash
Definition: autofmt.cxx:79
#define STR_AUTOFMTREDL_DEL_MORELINES
Definition: comcore.hxx:43
void FnCapitalStartSentence(SvxAutoCorrDoc &, const OUString &, bool bNormalPos, sal_Int32 nSttPos, sal_Int32 nEndPos, LanguageType eLang)
bool isLetterNumeric(const OUString &rStr, sal_Int32 nPos) const
sal_uInt16 sal_Unicode
#define STR_AUTOFMTREDL_CPTL_STT_WORD
Definition: comcore.hxx:25
void SetRedlineText_(sal_uInt16 nId)
Definition: autofmt.cxx:260
void JoinPrevPara()
join with the previous paragraph
Definition: autofmt.cxx:1329
bool IsBullet(TextFrameIndex nTextPos) const
Definition: frminf.cxx:193
ACFlags
WhichRangesContainer const aTextNodeSetRange(svl::Items< RES_CHRATR_BEGIN, RES_CHRATR_END-1, RES_PARATR_BEGIN, RES_PARATR_END-1, RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1, RES_FRMATR_BEGIN, RES_FRMATR_END-1, RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, XATTR_FILL_FIRST, XATTR_FILL_LAST >)
SwIndex nContent
Definition: pam.hxx:39
const SwRect & getFrameArea() const
Definition: frame.hxx:179
#define STR_AUTOFMTREDL_USE_REPLACE
Definition: comcore.hxx:24
bool CanJoin(const SwTextFrame *pNextFrame) const
Definition: autofmt.cxx:189
bool SetTextFormatColl(const SwPaM &rRg, SwTextFormatColl *pFormat, const bool bReset=true, const bool bResetListAttrs=false, SwRootFrame const *pLayout=nullptr)
Add 4th optional parameter .
Definition: docfmt.cxx:1083
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:426
static const sal_Int16 Medium
#define STR_AUTOFMTREDL_TYPO
Definition: comcore.hxx:27
constexpr TypedWhichId< SwFormatDrop > RES_PARATR_DROP(70)
void SetAllScriptItem(SfxItemSet &rSet, const SfxPoolItem &rItem)
Definition: poolfmt.cxx:41
bool IsFilled(const sal_uInt8 nPercent) const
Definition: frminf.cxx:74
SVX_NUM_ARABIC
void GoNextPara()
Definition: autofmt.cxx:296
virtual void DoUndo(bool const bDoUndo)=0
Enable/Disable Undo.
For internal use only.
sal_uInt16 GetDigitLevel(const SwTextFrame &rFrame, TextFrameIndex &rPos, OUString *pPrefix=nullptr, OUString *pPostfix=nullptr, OUString *pNumTypes=nullptr) const
Definition: autofmt.cxx:750
void Width(tools::Long nNew)
Definition: swrect.hxx:189
SVX_NUM_ROMAN_UPPER
void SetFormatItemByAutoFormat(const SwPaM &rPam, const SfxItemSet &)
Definition: docfmt.cxx:1820
sal_uInt8 GetAutoFormatLvl() const
Definition: node.hxx:140
std::unique_ptr< CharClass > m_pCharClass
Definition: autofmt.cxx:100
void DelMoreLinesBlanks(bool bWithLineBreaks=false)
when using multiline paragraphs delete the "left" and/or "right" margins
Definition: autofmt.cxx:1292
#define STR_AUTOFMTREDL_SET_TMPL_TEXT
Definition: comcore.hxx:37
Numbering symbols.
Definition: poolfmt.hxx:117
SVX_NUM_ROMAN_LOWER
bool IsProtectFlag() const
Definition: section.hxx:187
SwDoc * GetDoc() const
Definition: viewsh.hxx:282
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:161
void GotoNextLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1474
Text body indent.
Definition: poolfmt.hxx:254
RedlineFlags on.
bool IsEmpty() const
Definition: swrect.hxx:304
virtual bool DoesUndo() const =0
Is Undo enabled?
void BuildEnum(sal_uInt16 nLvl, sal_uInt16 nDigitLevel)
Definition: autofmt.cxx:1466
SwPaM * GetNext()
Definition: pam.hxx:265
SwTwips GetFirstIndent() const
Definition: frminf.cxx:205
sal_uInt16 GetPoolFormatId() const
Get and set Pool style IDs.
Definition: format.hxx:163
void FnCapitalStartWord(SvxAutoCorrDoc &, const OUString &, sal_Int32 nSttPos, sal_Int32 nEndPos, LanguageType eLang)
LanguageType m_eCharClassLang
Definition: autofmt.cxx:101
SwRect GetPaintSwRect()
Page number etc.
Definition: frmpaint.cxx:454
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:333
SVX_NUM_CHAR_SPECIAL
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:461
const SwTextFrame * GetNextNode(bool isCheckEnd=true) const
Definition: autofmt.cxx:359
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:457
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:502
static bool IsBlanksInString(const SwTextFrame &)
Definition: autofmt.cxx:410
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1306
virtual bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND)=0
Insert string into existing text node at position rRg.Point().
tools::Long GetTextLeft() const
sal_Unicode GetQuote(sal_Unicode cInsChar, bool bSttQuote, LanguageType eLang) const
void DeleteSelImpl(SwPaM &rDelPam, SwPaM &rPamToCorrect)
Definition: autofmt.cxx:1175
constexpr sal_uInt16 lNumberIndent
Definition: swtypes.hxx:100
#define STR_AUTOFMTREDL_SET_TMPL_TEXT_INDENT
Definition: comcore.hxx:40
SVX_NUM_CHARS_LOWER_LETTER
bool IsInRightToLeftText() const
Definition: crsrsh.cxx:3452
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1270
FontPitch GetPitch()
void AutoFormat(const SvxSwAutoFormatFlags *pAFlags)
Set our styles according to the respective rules.
Definition: autofmt.cxx:2702
bool IsOneLine(const SwTextFrame &) const
Definition: autofmt.cxx:370
SvxAdjust
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:959
bool bAFormatDelSpacesBetweenLines
uno_Any a
void SetBulletFont(const vcl::Font *pFont)
#define STR_AUTOFMTREDL_DEL_EMPTY_PARA
Definition: comcore.hxx:23
bool IsOneLine() const
Definition: frminf.cxx:53
const SwPosition * GetPoint() const
Definition: pam.hxx:208
void AutoFormatBySplitNode()
Definition: autofmt.cxx:2740
#define STR_AUTOFMTREDL_BOLD
Definition: comcore.hxx:31
#define STR_AUTOFMTREDL_FRACTION
Definition: comcore.hxx:32
const vcl::Font & GetDefBulletFont()
retrieve font used for the default bullet list characters
Definition: number.cxx:1391
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
#define LANGUAGE_SYSTEM
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2248
Text body.
Definition: poolfmt.hxx:251
sal_Int32 GetBigIndent(TextFrameIndex &rCurrentSpacePos) const
Definition: autofmt.cxx:483
SvxAutoCorrect * GetAutoCorrect()
bool FnAddNonBrkSpace(SvxAutoCorrDoc &, const OUString &, sal_Int32 nEndPos, LanguageType eLang, bool &io_bNbspRunNext)
bool IsHiddenFlag() const
Definition: section.hxx:186
SwNodeIndex m_aNdIdx
Definition: autofmt.cxx:91
SwContentNode * GetContentNode()
Definition: node.hxx:625
SwNodeOffset GetIndex() const
Definition: node.hxx:292
vector_type::size_type size_type
Definition: docary.hxx:222
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:206
tools::Long GetLeft() const
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:223
const SvxAdjustItem & GetAdjust(bool=true) const
Definition: paratr.hxx:194
Marks a character position inside a document model node.
Definition: index.hxx:33
float u
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2834
bool FnSetINetAttr(SvxAutoCorrDoc &, const OUString &, sal_Int32 nSttPos, sal_Int32 nEndPos, LanguageType eLang)
const sal_Unicode pBulletChar[6]
Definition: autofmt.cxx:75
short GetTextFirstLineOffset() const
bool SetRedlineText(sal_uInt16 nId)
Definition: autofmt.cxx:210
SwTextFrame * GetFormatted(bool bForceQuickFormat=false)
In case the SwLineLayout was cleared out of the s_pTextCache, recreate it.
Definition: txtfrm.cxx:3392
Marks a node in the document model.
Definition: ndindex.hxx:30
bool IsEndNode() const
Definition: node.hxx:642
virtual bool ReplaceRange(SwPaM &rPam, const OUString &rNewStr, const bool bRegExReplace)=0
Replace selected range in a TextNode with string.
CharClass & GetCharClass(LanguageType eLang) const
Definition: autofmt.cxx:121
sal_uInt16 m_nRedlAutoFormatSeqId
Definition: autofmt.cxx:103
bool HasSwAttrSet() const
Definition: node.hxx:458
ring_container GetRingContainer()
Definition: ring.hxx:240
void SetDistance(sal_uInt16 nNew, SvxBoxItemLine nLine)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
static sal_uInt16 GetNumIndent(sal_uInt8 nLvl)
Definition: number.cxx:168
OUString lowercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
vcl::Font aByInputBulletFont
void SetTextFormatCollByAutoFormat(const SwPosition &rPos, sal_uInt16 nPoolId, const SfxItemSet *pSet)
Definition: docfmt.cxx:1772
SwEditShell * m_pEditShell
Definition: autofmt.cxx:94
const int cnPosEmDash
Definition: autofmt.cxx:76
void BuildHeadLine(sal_uInt16 nLvl)
Definition: autofmt.cxx:1876
SwNodeIndex m_aEndNdIdx
Definition: autofmt.cxx:92
Represents the style of a text portion.
Definition: charfmt.hxx:26
#define STR_AUTOFMTREDL_CPTL_STT_SENT
Definition: comcore.hxx:26
void SetAutoFormatRedlineComment(const OUString *pText, sal_uInt16 nSeqNo=0)
Set comment-text for Redline.
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1234
show all deletes
tools::Long SwTwips
Definition: swtypes.hxx:51
#define STR_AUTOFMTREDL_SET_TMPL_INDENT
Definition: comcore.hxx:38
const SwPosition * Start() const
Definition: pam.hxx:213
Text body first line indent.
Definition: poolfmt.hxx:252
SwPaM m_aDelPam
Definition: autofmt.cxx:90
static SvxSwAutoFormatFlags * s_pAutoFormatFlags
Definition: editsh.hxx:140
SwTextFrameInfo & SetFrame(const SwTextFrame *pNew)
Definition: frminf.hxx:65
void BuildText()
Definition: autofmt.cxx:1428
bool DeleteJoinCurNextPara(SwTextFrame const *pNextFrame, bool bIgnoreLeadingBlanks=false)
Definition: autofmt.cxx:1205
virtual const SwRangeRedline * GetRedline(const SwPosition &rPos, SwRedlineTable::size_type *pFndPos) const =0
void DeleteLeadingTrailingBlanks(bool bStart=true, bool bEnd=true)
delete in the node start and/or end
Definition: autofmt.cxx:1080
SwPaM * GetPrev()
Definition: pam.hxx:269
#define STR_AUTOFMTREDL_SET_TMPL_HEADLINE
Definition: comcore.hxx:41
ignore Redlines
const sal_Unicode cStarSymbolEnDash
Definition: autofmt.cxx:78
#define STR_AUTOFMTREDL_DETECT_URL
Definition: comcore.hxx:33
#define STR_AUTOFMTREDL_SET_NUMBER_BULLET
Definition: comcore.hxx:42
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void SetAttrListLevel(int nLevel)
Sets the list level of this text node.
Definition: ndtxt.cxx:4110
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
static const sal_Int16 Hairline
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:195
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(105)
virtual bool TransliterateRTLWord(sal_Int32 &rSttPos, sal_Int32 nEndPos, bool bApply=false) override
Definition: acorrect.cxx:513
SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
Definition: number.cxx:1557
bool IsDefBulletFontUserDefined()
determine if default bullet font is user defined
Definition: number.cxx:1386
static SvxSwAutoFormatFlags * GetAutoFormatFlags()
Definition: autofmt.cxx:2801
static bool HasBreakAttr(const SwTextFrame &)
Definition: autofmt.cxx:1049
constexpr short lBulletFirstLineOffset
Definition: swtypes.hxx:99
SwTextFrame * m_pCurTextFrame
Definition: autofmt.cxx:97
unsigned char sal_uInt8
const std::vector< OUString > & GetAutoFormatNameLst() const
Definition: shellres.hxx:88
static const sal_Int16 Thin
#define STR_AUTOFMTREDL_UNDER
Definition: comcore.hxx:30
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
#define STR_AUTOFMTREDL_TRANSLITERATE_RTL
Definition: comcore.hxx:45
#define STR_AUTOFMTREDL_ORDINAL
Definition: comcore.hxx:35
virtual void SetRedlineFlags(RedlineFlags eMode)=0
Set a new redline mode.
sal_Int32 GetIndex() const
Definition: index.hxx:91
void SetProgressState(tools::Long nPosition, SwDocShell const *pDocShell)
Definition: mainwn.cxx:82
SwNodes & GetNodes()
Definition: doc.hxx:408
const SwPosition * End() const
Definition: pam.hxx:218
bool IsRightToLeft() const
Definition: frame.hxx:987
static bool IsEmptyLine(const SwTextFrame &rFrame)
Definition: autofmt.cxx:140
virtual bool ChgAutoCorrWord(sal_Int32 &rSttPos, sal_Int32 nEndPos, SvxAutoCorrect &rACorrect, OUString *pPara) override
Definition: acorrect.cxx:371
SvxSwAutoFormatFlags m_aFlags
Definition: autofmt.cxx:89
void * p
#define STR_AUTOFMTREDL_SET_TMPL_NEG_INDENT
Definition: comcore.hxx:39
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
void BuildNegIndent(SwTwips nSpaces)
Definition: autofmt.cxx:1792
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
static const sal_Unicode * StrChr(const sal_Unicode *pSrc, sal_Unicode c)
Definition: autofmt.cxx:225
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:724
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
static sal_Int32 GetTrailingBlanks(const OUString &rStr)
Definition: autofmt.cxx:720
const SwTextFrame * GetFrame() const
Definition: frminf.hxx:64
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:358
void GetSpaces(std::vector< std::pair< TextFrameIndex, TextFrameIndex >> &, bool bWithLineBreak) const
Definition: frminf.cxx:154
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
SwNodeOffset Count() const
Definition: ndarr.hxx:141
void GotoPrevLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1444
SwTwips GetCharPos(TextFrameIndex nChar, bool bCenter=true) const
Definition: frminf.cxx:107
SwNodeOffset m_nEndNdIdx
Definition: autofmt.cxx:99
SwTextNode const * pLastNode
mainly for sanity checks
Definition: txtfrm.hxx:972
static OUString DelLeadingBlanks(const OUString &rStr)
Definition: autofmt.cxx:687
bool m_bMoreLines
Definition: autofmt.cxx:119
#define STR_AUTOFMTREDL_END
Definition: comcore.hxx:47
bool IsFirstCharCapital(const SwTextFrame &rNd) const
Definition: autofmt.cxx:731
virtual RedlineFlags GetRedlineFlags() const =0
Query the currently set redline mode.
bool IsEnumericChar(const SwTextFrame &) const
Definition: autofmt.cxx:387
SwAutoFormat(SwEditShell *pEdShell, SvxSwAutoFormatFlags const &rFlags, SwNodeIndex const *pSttNd=nullptr, SwNodeIndex const *pEndNd=nullptr)
Definition: autofmt.cxx:2236
bool FnChgWeightUnderl(SvxAutoCorrDoc &, const OUString &, sal_Int32 nEndPos)
bool IsTableNode() const
Definition: node.hxx:650
constexpr short lBulletIndent
Definition: swtypes.hxx:98
static bool IsSentenceAtEnd(const SwTextFrame &rTextFrame)
is a dot at the end ??
Definition: autofmt.cxx:1067
Text body hanging indent.
Definition: poolfmt.hxx:253
SwSectionNode * GetSectionNode()
Definition: node.hxx:617
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:476
bool Pop(PopMode)
delete cursor
Definition: crsrsh.cxx:2270
ACFlags GetFlags() const
bool DoUnderline()
Definition: autofmt.cxx:526
void BuildIndent()
Definition: autofmt.cxx:1347
OUString SetNumRule(const SwPaM &, const SwNumRule &, bool bCreateNewList, SwRootFrame const *pLayout=nullptr, const OUString &sContinuedListId=OUString(), bool bSetItem=true, const bool bResetIndentAttrs=false)
Accept changes of outline styles for OutlineRule.
Definition: docnum.cxx:868
constexpr TypedWhichId< SwParaConnectBorderItem > RES_PARATR_CONNECT_BORDER(78)
bool IsFastFullLine(const SwTextFrame &) const
Definition: autofmt.cxx:376
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
static void SetAutoFormatFlags(SvxSwAutoFormatFlags const *)
Definition: autofmt.cxx:2809
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:206
const int cnPosEnDash
Definition: autofmt.cxx:76
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...
const SwTable * InsertTable(const SwInsertTableOptions &rInsTableOpts, const SwPosition &rPos, sal_uInt16 nRows, sal_uInt16 nCols, sal_Int16 eAdjust, const SwTableAutoFormat *pTAFormat=nullptr, const std::vector< sal_uInt16 > *pColArr=nullptr, bool bCalledFromShell=false, bool bNewModel=true)
Insert new table at position.
Definition: ndtbl.cxx:341
SwTextFrame * GetFrame(const SwTextNode &rTextNd) const
get the FORMATTED TextFrame
Definition: autofmt.cxx:232
CharClass & GetAppCharClass()
Definition: init.cxx:705
bool IsTextNode() const
Definition: node.hxx:646
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1249
const sal_uInt16 cnNumBullColls
Definition: autofmt.cxx:85
static const sal_Int16 Thick
constexpr TypedWhichId< SvxAdjustItem > RES_PARATR_ADJUST(64)
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
SwTextNode * m_pCurTextNd
Definition: autofmt.cxx:96
constexpr TypedWhichId< SvxShadowItem > RES_SHADOW(107)
rtl_TextEncoding GetCharSet() const
sal_uInt16 nPos
SwTextFormatColl & GetNextTextFormatColl() const
Definition: fmtcol.hxx:104
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1318
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:864
static bool IsSpace(const sal_Unicode c)
Definition: autofmt.cxx:131
bool DoTable()
Definition: autofmt.cxx:607
void SetAutoFormatRedline(bool bFlag)
Definition: doc.hxx:1447
#define STR_AUTOFMTREDL_DASH
Definition: comcore.hxx:34
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxItemLine nLine)
SwFrame * GetNext()
Definition: frame.hxx:676
Base class of the Writer document model elements.
Definition: node.hxx:81
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:858
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo