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