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