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