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