LibreOffice Module sw (master)  1
autofmt.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <hintids.hxx>
21 
22 #include <unotools/charclass.hxx>
23 
24 #include <editeng/boxitem.hxx>
25 #include <editeng/lrspitem.hxx>
27 #include <editeng/adjustitem.hxx>
28 #include <editeng/tstpitem.hxx>
29 #include <editeng/fontitem.hxx>
30 #include <editeng/langitem.hxx>
31 #include <editeng/acorrcfg.hxx>
32 
33 #include <swwait.hxx>
34 #include <fmtpdsc.hxx>
35 #include <doc.hxx>
36 #include <IDocumentUndoRedo.hxx>
39 #include <redline.hxx>
40 #include <unocrsr.hxx>
41 #include <docary.hxx>
42 #include <editsh.hxx>
43 #include <index.hxx>
44 #include <pam.hxx>
45 #include <swundo.hxx>
46 #include <poolfmt.hxx>
47 #include <ndtxt.hxx>
48 #include <rootfrm.hxx>
49 #include <txtfrm.hxx>
50 #include <frminf.hxx>
51 #include <pagedesc.hxx>
52 #include <paratr.hxx>
53 #include <acorrect.hxx>
54 #include <shellres.hxx>
55 #include <section.hxx>
56 #include <frmatr.hxx>
57 #include <charatr.hxx>
58 #include <mdiexp.hxx>
59 #include <strings.hrc>
60 #include <comcore.hxx>
61 #include <numrule.hxx>
62 #include <itabenum.hxx>
63 
64 #include <memory>
65 
66 using namespace ::com::sun::star;
67 
68 //JP 16.12.99: definition:
69 // from pos cPosEnDash to cPosEmDash all chars changed to em dashes,
70 // from pos cPosEmDash to cPosEnd all chars changed to em dashes
71 // all other chars are changed to the user configuration
72 
73 const sal_Unicode pBulletChar[6] = { '+', '*', '-', 0x2013, 0x2014, 0 };
74 const int cnPosEnDash = 2, cnPosEmDash = 4;
75 
78 
80 
81 // Number of num-/bullet-paragraph templates. MAXLEVEL will soon be raised
82 // to x, but not the number of templates. (Artifact from <= 4.0)
83 const sal_uInt16 cnNumBullColls = 4;
84 
86 {
88  SwPaM m_aDelPam; // a Pam that can be used
89  SwNodeIndex m_aNdIdx; // the index on the current TextNode
90  SwNodeIndex m_aEndNdIdx; // index on the end of the area
91 
94  SwTextNode* m_pCurTextNd; // the current TextNode
95  SwTextFrame* m_pCurTextFrame; // frame of the current TextNode
96  sal_uLong m_nEndNdIdx; // for the percentage-display
97  mutable std::unique_ptr<CharClass> m_pCharClass; // Character classification
99 
101 
102  enum
103  {
104  NONE = 0,
105  DELIM = 1,
106  DIGIT = 2,
107  CHG = 4,
113  };
114 
115  bool m_bEnd : 1;
116  bool m_bMoreLines : 1;
117 
119  {
120  if( !m_pCharClass || eLang != m_eCharClassLang )
121  {
122  m_pCharClass.reset( new CharClass( LanguageTag( eLang ) ) );
123  m_eCharClassLang = eLang;
124  }
125  return *m_pCharClass;
126  }
127 
128  static bool IsSpace( const sal_Unicode c )
129  { return (' ' == c || '\t' == c || 0x0a == c|| 0x3000 == c /* Jap. space */); }
130 
131  void SetColl( sal_uInt16 nId, bool bHdLineOrText = false );
132  void GoNextPara();
133  static bool HasObjects(const SwTextFrame &);
134 
135  // TextNode methods
136  const SwTextFrame * GetNextNode(bool isCheckEnd = true) const;
137  static bool IsEmptyLine(const SwTextFrame & rFrame)
138  {
139  return rFrame.GetText().isEmpty()
140  || rFrame.GetText().getLength() == GetLeadingBlanks(rFrame.GetText());
141  }
142 
143  bool IsOneLine(const SwTextFrame &) const;
144  bool IsFastFullLine(const SwTextFrame &) const;
145  bool IsNoAlphaLine(const SwTextFrame &) const;
146  bool IsEnumericChar(const SwTextFrame &) const;
147  static bool IsBlanksInString(const SwTextFrame&);
148  sal_uInt16 CalcLevel(const SwTextFrame&, sal_uInt16 *pDigitLvl = nullptr) const;
149  sal_Int32 GetBigIndent(TextFrameIndex & rCurrentSpacePos) const;
150 
151  static OUString DelLeadingBlanks(const OUString& rStr);
152  static OUString DelTrailingBlanks( const OUString& rStr );
153  static sal_Int32 GetLeadingBlanks( const OUString& rStr );
154  static sal_Int32 GetTrailingBlanks( const OUString& rStr );
155 
156  bool IsFirstCharCapital(const SwTextFrame & rNd) const;
157  sal_uInt16 GetDigitLevel(const SwTextFrame& rFrame, TextFrameIndex& rPos,
158  OUString* pPrefix = nullptr, OUString* pPostfix = nullptr,
159  OUString* pNumTypes = nullptr ) const;
161  SwTextFrame* GetFrame( const SwTextNode& rTextNd ) const;
162  SwTextFrame * EnsureFormatted(SwTextFrame const&) const;
163 
164  void BuildIndent();
165  void BuildText();
166  void BuildTextIndent();
167  void BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel );
168  void BuildNegIndent( SwTwips nSpaces );
169  void BuildHeadLine( sal_uInt16 nLvl );
170 
171  static bool HasBreakAttr(const SwTextFrame &);
172  void DeleteSel( SwPaM& rPam );
173  void DeleteSelImpl(SwPaM & rDelPam, SwPaM & rPamToCorrect);
174  bool DeleteJoinCurNextPara(SwTextFrame const* pNextFrame, bool bIgnoreLeadingBlanks = false);
176  void DeleteLeadingTrailingBlanks( bool bStart = true, bool bEnd = true );
177  void DelEmptyLine( bool bTstNextPara = true );
180  void DelMoreLinesBlanks( bool bWithLineBreaks = false );
182  void JoinPrevPara();
184  void AutoCorrect(TextFrameIndex nSttPos = TextFrameIndex(0));
185 
186  bool CanJoin(const SwTextFrame * pNextFrame) const
187  {
188  return !m_bEnd && pNextFrame
189  && !IsEmptyLine(*pNextFrame)
190  && !IsNoAlphaLine(*pNextFrame)
191  && !IsEnumericChar(*pNextFrame)
192  // check the last / first nodes here...
193  && ((COMPLETE_STRING - 50 - pNextFrame->GetTextNodeFirst()->GetText().getLength())
194  > (m_pCurTextFrame->GetMergedPara()
195  ? m_pCurTextFrame->GetMergedPara()->pLastNode
196  : m_pCurTextNd)->GetText().getLength())
197  && !HasBreakAttr(*pNextFrame);
198  }
199 
201  static bool IsSentenceAtEnd(const SwTextFrame & rTextFrame);
202 
203  bool DoUnderline();
204  bool DoTable();
205 
206  void SetRedlineText_( sal_uInt16 nId );
207  bool SetRedlineText( sal_uInt16 nId ) {
208  if( m_aFlags.bWithRedlining )
209  SetRedlineText_( nId );
210  return true;
211  }
213  if( m_aFlags.bWithRedlining )
215  }
216 
217 public:
218  SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags const & rFlags,
219  SwNodeIndex const * pSttNd = nullptr, SwNodeIndex const * pEndNd = nullptr );
220 };
221 
222 static const sal_Unicode* StrChr( const sal_Unicode* pSrc, sal_Unicode c )
223 {
224  while( *pSrc && *pSrc != c )
225  ++pSrc;
226  return *pSrc ? pSrc : nullptr;
227 }
228 
230 {
231  // get the Frame
232  const SwContentFrame *pFrame = rTextNd.getLayoutFrame( m_pEditShell->GetLayout() );
233  assert(pFrame && "For Autoformat a Layout is needed");
234  return EnsureFormatted(*static_cast<SwTextFrame const*>(pFrame));
235 }
236 
238 {
239  SwTextFrame *const pFrame(const_cast<SwTextFrame*>(&rFrame));
240  if( m_aFlags.bAFormatByInput && !pFrame->isFrameAreaDefinitionValid() )
241  {
243  SwRect aTmpFrame( pFrame->getFrameArea() );
244  SwRect aTmpPrt( pFrame->getFramePrintArea() );
245  pFrame->Calc(pFrame->getRootFrame()->GetCurrShell()->GetOut());
246 
247  if( pFrame->getFrameArea() != aTmpFrame || pFrame->getFramePrintArea() != aTmpPrt ||
248  !pFrame->GetPaintSwRect().IsEmpty())
249  {
250  pFrame->SetCompletePaint();
251  }
252  }
253 
254  return pFrame->GetFormatted();
255 }
256 
257 void SwAutoFormat::SetRedlineText_( sal_uInt16 nActionId )
258 {
259  OUString sText;
260  sal_uInt16 nSeqNo = 0;
261  if( STR_AUTOFMTREDL_END > nActionId )
262  {
263  sText = SwViewShell::GetShellRes()->GetAutoFormatNameLst()[ nActionId ];
264  switch( nActionId )
265  {
268 
269  // AutoCorrect actions
281  nSeqNo = ++m_nRedlAutoFormatSeqId;
282  break;
283  }
284  }
285 #if OSL_DEBUG_LEVEL > 0
286  else
287  sText = "Action text is missing";
288 #endif
289 
290  m_pDoc->GetDocumentRedlineManager().SetAutoFormatRedlineComment( &sText, nSeqNo );
291 }
292 
294 {
295  SwNode* pNewNd = nullptr;
296  do {
297  // has to be checked twice before and after incrementation
298  if( m_aNdIdx.GetIndex() >= m_aEndNdIdx.GetIndex() )
299  {
300  m_bEnd = true;
301  return;
302  }
303 
304  sw::GotoNextLayoutTextFrame(m_aNdIdx, m_pEditShell->GetLayout());
305  if( m_aNdIdx.GetIndex() >= m_aEndNdIdx.GetIndex() )
306  {
307  m_bEnd = true;
308  return;
309  }
310  else
311  pNewNd = &m_aNdIdx.GetNode();
312 
313  // not a TextNode ->
314  // TableNode : skip table
315  // NoTextNode : skip nodes
316  // EndNode : at the end, terminate
317  if( pNewNd->IsEndNode() )
318  {
319  m_bEnd = true;
320  return;
321  }
322  else if( pNewNd->IsTableNode() )
323  m_aNdIdx = *pNewNd->EndOfSectionNode();
324  else if( pNewNd->IsSectionNode() )
325  {
326  const SwSection& rSect = pNewNd->GetSectionNode()->GetSection();
327  if( rSect.IsHiddenFlag() || rSect.IsProtectFlag() )
328  m_aNdIdx = *pNewNd->EndOfSectionNode();
329  }
330  } while( !pNewNd->IsTextNode() );
331 
332  if( !m_aFlags.bAFormatByInput )
333  ::SetProgressState( m_aNdIdx.GetIndex() + m_nEndNdIdx - m_aEndNdIdx.GetIndex(),
334  m_pDoc->GetDocShell() );
335 
336  m_pCurTextNd = static_cast<SwTextNode*>(pNewNd);
337  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
338 }
339 
341 {
342  // Is there something bound to the paragraph in the paragraph
343  // like Frames, DrawObjects, ...
344  SwNodeIndex node(*rFrame.GetTextNodeFirst());
345  do
346  {
347  if (node.GetNode().GetAnchoredFlys() != nullptr)
348  {
349  assert(!node.GetNode().GetAnchoredFlys()->empty());
350  return true;
351  }
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( static_cast<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( static_cast<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 = static_cast<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 = static_cast<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(m_pCurTextFrame->GetText().getLength()));
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(TextFrameIndex(0));
1271  }
1272  }
1273  else
1274  {
1275  *m_aDelPam.GetMark() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
1276  pTNd = m_pCurTextNd;
1277  }
1278  if( pTNd )
1279  DeleteSel( m_aDelPam );
1280 
1281  m_aDelPam.DeleteMark();
1282  ClearRedlineText();
1283  // note: this likely has deleted m_pCurTextFrame - update it...
1284  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
1285  m_pCurTextFrame = m_pCurTextNd ? GetFrame( *m_pCurTextNd ) : nullptr;
1286 }
1287 
1288 void SwAutoFormat::DelMoreLinesBlanks( bool bWithLineBreaks )
1289 {
1290  if( !(m_aFlags.bAFormatByInput
1292  : m_aFlags.bAFormatDelSpacesBetweenLines) )
1293  return;
1294 
1295  // delete all blanks on the left and right of the indentation
1296  m_aDelPam.DeleteMark();
1297 
1298  SwTextFrameInfo aFInfo( m_pCurTextFrame );
1299  std::vector<std::pair<TextFrameIndex, TextFrameIndex>> spaces;
1300  aFInfo.GetSpaces(spaces, !m_aFlags.bAFormatByInput || bWithLineBreaks);
1301 
1302  // tdf#123285 iterate backwards - delete invalidates following indexes
1303  for (auto iter = spaces.rbegin(); iter != spaces.rend(); ++iter)
1304  {
1305  auto & rSpaceRange(*iter);
1306  assert(rSpaceRange.first != rSpaceRange.second);
1307  bool const bHasBlanks = HasSelBlanks(
1308  m_pCurTextFrame, rSpaceRange.first,
1309  m_pCurTextFrame, rSpaceRange.second);
1310  if (rSpaceRange.first != rSpaceRange.second)
1311  {
1312  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(rSpaceRange.first);
1313  m_aDelPam.SetMark();
1314  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(rSpaceRange.second);
1315  DeleteSel(m_aDelPam);
1316  if (!bHasBlanks)
1317  {
1318  m_pDoc->getIDocumentContentOperations().InsertString(m_aDelPam, OUString(' '));
1319  }
1320  m_aDelPam.DeleteMark();
1321  }
1322  }
1323 }
1324 
1326 {
1327  m_aDelPam.DeleteMark();
1328  m_aDelPam.GetPoint()->nNode = *m_pCurTextFrame->GetTextNodeFirst();
1329  m_aDelPam.GetPoint()->nContent.Assign(m_pCurTextFrame->GetTextNodeFirst(), 0);
1330  m_aDelPam.SetMark();
1331 
1332  --m_aDelPam.GetPoint()->nNode;
1333  SwTextNode* pTNd = m_aDelPam.GetNode().GetTextNode();
1334  if( pTNd )
1335  {
1336  // use the previous text node first
1337  m_aDelPam.GetPoint()->nContent.Assign(pTNd, pTNd->GetText().getLength());
1338  DeleteSel( m_aDelPam );
1339  }
1340  m_aDelPam.DeleteMark();
1341 }
1342 
1344 {
1346 
1347  // read all succeeding paragraphs that belong to this indentation
1348  bool bBreak = true;
1349  if( m_bMoreLines )
1350  DelMoreLinesBlanks( true );
1351  else
1352  bBreak = !IsFastFullLine(*m_pCurTextFrame)
1353  || IsBlanksInString(*m_pCurTextFrame)
1354  || IsSentenceAtEnd(*m_pCurTextFrame);
1356  if( !bBreak )
1357  {
1359  const SwTextFrame * pNextFrame = GetNextNode();
1360  if (pNextFrame && !m_bEnd)
1361  {
1362  do {
1363  bBreak = !IsFastFullLine(*pNextFrame)
1364  || IsBlanksInString(*pNextFrame)
1365  || IsSentenceAtEnd(*pNextFrame);
1366  if (DeleteJoinCurNextPara(pNextFrame))
1367  {
1368  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
1369  }
1370  if( bBreak )
1371  break;
1372  pNextFrame = GetNextNode();
1373  }
1374  while (CanJoin(pNextFrame)
1375  && !CalcLevel(*pNextFrame));
1376  }
1377  }
1379  AutoCorrect();
1380 }
1381 
1383 {
1385  // read all succeeding paragraphs that belong to this indentation
1386  bool bBreak = true;
1387  if( m_bMoreLines )
1388  DelMoreLinesBlanks( true );
1389  else
1390  bBreak = !IsFastFullLine(*m_pCurTextFrame)
1391  || IsBlanksInString(*m_pCurTextFrame)
1392  || IsSentenceAtEnd(*m_pCurTextFrame);
1393 
1394  if( m_aFlags.bAFormatByInput )
1395  {
1396  const_cast<SwTextNode*>(m_pCurTextFrame->GetTextNodeForParaProps())->SetAutoFormatLvl(
1397  static_cast<sal_uInt8>(CalcLevel(*m_pCurTextFrame)));
1398  }
1399 
1401  if( !bBreak )
1402  {
1404  const SwTextFrame * pNextFrame = GetNextNode();
1405  while (CanJoin(pNextFrame) &&
1406  CalcLevel(*pNextFrame))
1407  {
1408  bBreak = !IsFastFullLine(*pNextFrame)
1409  || IsBlanksInString(*pNextFrame)
1410  || IsSentenceAtEnd(*pNextFrame);
1411  if (DeleteJoinCurNextPara(pNextFrame))
1412  {
1413  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
1414  }
1415  if( bBreak )
1416  break;
1417  pNextFrame = GetNextNode();
1418  }
1419  }
1421  AutoCorrect();
1422 }
1423 
1425 {
1427  // read all succeeding paragraphs that belong to this text without indentation
1428  bool bBreak = true;
1429  if( m_bMoreLines )
1431  else
1432  bBreak = !IsFastFullLine(*m_pCurTextFrame)
1433  || IsBlanksInString(*m_pCurTextFrame)
1434  || IsSentenceAtEnd(*m_pCurTextFrame);
1435  SetColl( RES_POOLCOLL_TEXT, true );
1436  if( !bBreak )
1437  {
1439  const SwTextFrame * pNextFrame = GetNextNode();
1440  while (CanJoin(pNextFrame) &&
1441  !CalcLevel(*pNextFrame))
1442  {
1443  bBreak = !IsFastFullLine(*pNextFrame)
1444  || IsBlanksInString(*pNextFrame)
1445  || IsSentenceAtEnd(*pNextFrame);
1446  if (DeleteJoinCurNextPara(pNextFrame))
1447  {
1448  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
1449  }
1450  if( bBreak )
1451  break;
1452  const SwTextFrame *const pCurrNode = pNextFrame;
1453  pNextFrame = GetNextNode();
1454  if (!pNextFrame || pCurrNode == pNextFrame)
1455  break;
1456  }
1457  }
1459  AutoCorrect();
1460 }
1461 
1462 void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
1463 {
1465 
1466  bool bBreak = true;
1467 
1468  // first, determine current indentation and frame width
1469  SwTwips nFrameWidth = m_pCurTextFrame->getFramePrintArea().Width();
1470  SwTwips nLeftTextPos;
1471  {
1472  TextFrameIndex nPos(0);
1473  while (nPos < TextFrameIndex(m_pCurTextFrame->GetText().getLength())
1474  && IsSpace(m_pCurTextFrame->GetText()[sal_Int32(nPos)]))
1475  {
1476  ++nPos;
1477  }
1478 
1479  SwTextFrameInfo aInfo( m_pCurTextFrame );
1480  nLeftTextPos = aInfo.GetCharPos(nPos);
1481  nLeftTextPos -= m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().GetLRSpace().GetLeft();
1482  }
1483 
1484  if( m_bMoreLines )
1486  else
1487  bBreak = !IsFastFullLine(*m_pCurTextFrame)
1488  || IsBlanksInString(*m_pCurTextFrame)
1489  || IsSentenceAtEnd(*m_pCurTextFrame);
1490  bool bRTL = m_pEditShell->IsInRightToLeftText();
1492 
1493  bool bChgBullet = false, bChgEnum = false;
1494  TextFrameIndex nAutoCorrPos(0);
1495 
1496  // if numbering is set, get the current one
1497  SwNumRule aRule( m_pDoc->GetUniqueNumRuleName(),
1498  // #i89178#
1500 
1501  const SwNumRule* pCur = nullptr;
1502  if (m_aFlags.bSetNumRule)
1503  {
1504  pCur = m_pCurTextFrame->GetTextNodeForParaProps()->GetNumRule();
1505  if (pCur)
1506  {
1507  aRule = *pCur;
1508  }
1509  }
1510 
1511  // replace bullet character with defined one
1512  const OUString& rStr = m_pCurTextFrame->GetText();
1513  TextFrameIndex nTextStt(0);
1514  const sal_Unicode* pFndBulletChr = nullptr;
1515  if (m_aFlags.bChgEnumNum && 2 < rStr.getLength())
1516  pFndBulletChr = StrChr(pBulletChar, rStr[sal_Int32(nTextStt)]);
1517  if (nullptr != pFndBulletChr && IsSpace(rStr[sal_Int32(nTextStt) + 1]))
1518  {
1519  if( m_aFlags.bAFormatByInput )
1520  {
1521  if( m_aFlags.bSetNumRule )
1522  {
1525  bChgBullet = true;
1526  // Was the format already somewhere adjusted?
1527  if( !aRule.GetNumFormat( nLvl ) )
1528  {
1529  int nBulletPos = pFndBulletChr - pBulletChar;
1530  sal_Unicode cBullChar;
1531  const vcl::Font* pBullFnt( nullptr );
1532  if( nBulletPos < cnPosEnDash )
1533  {
1534  cBullChar = m_aFlags.cBullet;
1535  pBullFnt = &m_aFlags.aBulletFont;
1536  }
1537  else
1538  {
1539  cBullChar = nBulletPos < cnPosEmDash
1542  // #i63395#
1543  // Only apply user defined default bullet font
1545  {
1546  pBullFnt = &numfunc::GetDefBulletFont();
1547  }
1548  }
1549 
1550  sal_Int32 nAbsPos = lBulletIndent;
1551  SwTwips nSpaceSteps = nLvl
1552  ? nLeftTextPos / nLvl
1553  : lBulletIndent;
1554  for( sal_uInt8 n = 0; n < MAXLEVEL; ++n, nAbsPos = nAbsPos + nSpaceSteps )
1555  {
1556  SwNumFormat aFormat( aRule.Get( n ) );
1557  aFormat.SetBulletFont( pBullFnt );
1558  aFormat.SetBulletChar( cBullChar );
1559  aFormat.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
1560  // #i93908# clear suffix for bullet lists
1561  aFormat.SetPrefix(OUString());
1562  aFormat.SetSuffix(OUString());
1563  aFormat.SetFirstLineOffset( lBulletFirstLineOffset );
1564  aFormat.SetAbsLSpace( nAbsPos );
1565  if( !aFormat.GetCharFormat() )
1566  aFormat.SetCharFormat( pCFormat );
1567  if( bRTL )
1568  aFormat.SetNumAdjust( SvxAdjust::Right );
1569 
1570  aRule.Set( n, aFormat );
1571 
1572  if( n == nLvl &&
1573  nFrameWidth < ( nSpaceSteps * MAXLEVEL ) )
1574  nSpaceSteps = ( nFrameWidth - nLeftTextPos ) /
1575  ( MAXLEVEL - nLvl );
1576  }
1577  }
1578  }
1579  }
1580  else
1581  {
1582  bChgBullet = true;
1583  SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_BULLET_LEVEL1 + ( std::min( nLvl, cnNumBullColls ) * 4 )) );
1584  }
1585  }
1586  else
1587  {
1588  // Then it is a numbering
1589 
1590  //JP 21.11.97: The NumLevel is either the DigitLevel or, if the latter is not existent or 0,
1591  // it is determined by the indentation level.
1592 
1593  OUString aPostfix, aPrefix, aNumTypes;
1594  nDigitLevel = GetDigitLevel(*m_pCurTextFrame, nTextStt,
1595  &aPrefix, &aPostfix, &aNumTypes);
1596  if (USHRT_MAX != nDigitLevel)
1597  {
1598  bChgEnum = true;
1599 
1600  // Level 0 and Indentation, determine level by left indentation and default NumIndent
1601  if( !nDigitLevel && nLeftTextPos )
1602  nLvl = std::min( sal_uInt16( nLeftTextPos / lNumberIndent ),
1603  sal_uInt16( MAXLEVEL - 1 ) );
1604  else
1605  nLvl = nDigitLevel;
1606  }
1607 
1608  if( bChgEnum && m_aFlags.bSetNumRule )
1609  {
1610  if( !pCur ) // adjust NumRule if it is new
1611  {
1614 
1615  sal_Int32 nPrefixIdx{ 0 };
1616  if( !nDigitLevel )
1617  {
1618  SwNumFormat aFormat( aRule.Get( nLvl ) );
1619  aFormat.SetPrefix( aPrefix.getToken( 0, u'\x0001', nPrefixIdx ));
1620  aFormat.SetStart( static_cast<sal_uInt16>(aPrefix.getToken( 0, u'\x0001', nPrefixIdx ).toInt32()));
1621  aFormat.SetSuffix( aPostfix.getToken( 0, u'\x0001' ));
1622  aFormat.SetIncludeUpperLevels( 0 );
1623 
1624  if( !aFormat.GetCharFormat() )
1625  aFormat.SetCharFormat( pCFormat );
1626 
1627  if( !aNumTypes.isEmpty() )
1628  aFormat.SetNumberingType(static_cast<SvxNumType>(aNumTypes[ 0 ] - '0'));
1629 
1630  if( bRTL )
1631  aFormat.SetNumAdjust( SvxAdjust::Right );
1632  aRule.Set( nLvl, aFormat );
1633  }
1634  else
1635  {
1636  auto const nSpaceSteps = nLvl ? nLeftTextPos / nLvl : 0;
1637  sal_uInt16 n;
1638  sal_Int32 nPostfixIdx{ 0 };
1639  for( n = 0; n <= nLvl; ++n )
1640  {
1641  SwNumFormat aFormat( aRule.Get( n ) );
1642 
1643  if( !n )
1644  aFormat.SetPrefix( aPrefix.getToken( 0, u'\x0001', nPrefixIdx )); // token 0, read only on first loop
1645  aFormat.SetStart( static_cast<sal_uInt16>(aPrefix.getToken( 0, u'\x0001', nPrefixIdx ).toInt32() ));
1646  aFormat.SetSuffix( aPostfix.getToken( 0, u'\x0001', nPostfixIdx ));
1647  aFormat.SetIncludeUpperLevels( MAXLEVEL );
1648  if( n < aNumTypes.getLength() )
1649  aFormat.SetNumberingType(static_cast<SvxNumType>(aNumTypes[ n ] - '0'));
1650 
1651  aFormat.SetAbsLSpace( nSpaceSteps * n
1652  + lNumberIndent );
1653 
1654  if( !aFormat.GetCharFormat() )
1655  aFormat.SetCharFormat( pCFormat );
1656  if( bRTL )
1657  aFormat.SetNumAdjust( SvxAdjust::Right );
1658 
1659  aRule.Set( n, aFormat );
1660  }
1661 
1662  // Does it fit completely into the frame?
1663  bool bDefStep = nFrameWidth < (nSpaceSteps * MAXLEVEL);
1664  for( ; n < MAXLEVEL; ++n )
1665  {
1666  SwNumFormat aFormat( aRule.Get( n ) );
1667  aFormat.SetIncludeUpperLevels( MAXLEVEL );
1668  if( bDefStep )
1669  aFormat.SetAbsLSpace( nLeftTextPos +
1670  SwNumRule::GetNumIndent(static_cast<sal_uInt8>(n-nLvl)));
1671  else
1672  aFormat.SetAbsLSpace( nSpaceSteps * n
1673  + lNumberIndent );
1674  aRule.Set( n, aFormat );
1675  }
1676  }
1677  }
1678  }
1679  else if( !m_aFlags.bAFormatByInput )
1680  SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_NUM_LEVEL1 + ( std::min( nLvl, cnNumBullColls ) * 4 ) ));
1681  else
1682  bChgEnum = false;
1683  }
1684 
1685  if ( bChgEnum || bChgBullet )
1686  {
1687  m_aDelPam.DeleteMark();
1688  m_aDelPam.GetPoint()->nNode = *m_pCurTextFrame->GetTextNodeForParaProps();
1689 
1690  if( m_aFlags.bSetNumRule )
1691  {
1692  if( m_aFlags.bAFormatByInput )
1693  {
1694  m_aDelPam.SetMark();
1695  SwTextFrame const*const pNextFrame = GetNextNode(false);
1696  assert(pNextFrame);
1697  m_aDelPam.GetMark()->nNode = *pNextFrame->GetTextNodeForParaProps();
1698  m_aDelPam.GetNode(false).GetTextNode()->SetAttrListLevel( nLvl );
1699  }
1700 
1701  const_cast<SwTextNode*>(m_pCurTextFrame->GetTextNodeForParaProps())->SetAttrListLevel(nLvl);
1702 
1703  // start new list
1704  m_pDoc->SetNumRule(m_aDelPam, aRule, true, m_pEditShell->GetLayout());
1705  m_aDelPam.DeleteMark();
1706 
1707  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
1708  }
1709  else
1710  {
1711  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
1712  bChgEnum ? nTextStt : TextFrameIndex(0));
1713  }
1714  m_aDelPam.SetMark();
1715 
1716  if ( bChgBullet )
1717  nTextStt += TextFrameIndex(2);
1718 
1719  while (nTextStt < TextFrameIndex(rStr.getLength()) && IsSpace(rStr[sal_Int32(nTextStt)]))
1720  nTextStt++;
1721 
1722  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nTextStt);
1723  DeleteSel( m_aDelPam );
1724 
1725  if( !m_aFlags.bSetNumRule )
1726  {
1727  OUString sChgStr('\t');
1728  if( bChgBullet )
1729  sChgStr = OUStringChar( m_aFlags.cBullet ) + sChgStr;
1730  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, sChgStr );
1731 
1732  SfxItemSet aSet( m_pDoc->GetAttrPool(), aTextNodeSetRange );
1733  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
1734  assert(&m_aDelPam.GetPoint()->nNode.GetNode() == m_pCurTextFrame->GetTextNodeForParaProps());
1735  if( bChgBullet )
1736  {
1737  m_aDelPam.SetMark();
1738  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(1));
1739  SetAllScriptItem( aSet,
1741  m_aFlags.aBulletFont.GetFamilyName(),
1742  m_aFlags.aBulletFont.GetStyleName(),
1743  m_aFlags.aBulletFont.GetPitch(),
1744  m_aFlags.aBulletFont.GetCharSet(),
1745  RES_CHRATR_FONT ) );
1746  m_pDoc->SetFormatItemByAutoFormat( m_aDelPam, aSet );
1747  m_aDelPam.DeleteMark();
1748  nAutoCorrPos = TextFrameIndex(2);
1749  aSet.ClearItem();
1750  }
1752  aTStops.Insert( SvxTabStop( 0 ) );
1753  aSet.Put( aTStops );
1754  assert(&m_aDelPam.GetPoint()->nNode.GetNode() == m_pCurTextFrame->GetTextNodeForParaProps());
1755  m_pDoc->SetFormatItemByAutoFormat( m_aDelPam, aSet );
1756  }
1757  }
1758 
1759  if( bBreak )
1760  {
1761  AutoCorrect( nAutoCorrPos ); /* Offset due to Bullet + Tab */
1762  return;
1763  }
1764 
1765  const SwTextFrame * pNextFrame = GetNextNode();
1766  while (CanJoin(pNextFrame)
1767  && nLvl == CalcLevel(*pNextFrame))
1768  {
1770  bBreak = !IsFastFullLine(*pNextFrame)
1771  || IsBlanksInString(*pNextFrame)
1772  || IsSentenceAtEnd(*pNextFrame);
1773  if (DeleteJoinCurNextPara(pNextFrame))
1774  {
1775  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
1776  }
1777  if( bBreak )
1778  break;
1779  const SwTextFrame *const pCurrNode = pNextFrame;
1780  pNextFrame = GetNextNode();
1781  if (!pNextFrame || pCurrNode == pNextFrame)
1782  break;
1783  }
1784  DeleteLeadingTrailingBlanks( false );
1785  AutoCorrect( nAutoCorrPos );
1786 }
1787 
1789 {
1791  // Test of contraposition (n words, divided by spaces/tabs, with same indentation in 2nd line)
1792 
1793  // read all succeeding paragraphs that belong to this enumeration
1794  bool bBreak = true;
1795  TextFrameIndex nSpacePos(0);
1796  const sal_Int32 nTextPos = GetBigIndent( nSpacePos );
1797  if( m_bMoreLines )
1798  DelMoreLinesBlanks( true );
1799  else
1800  bBreak = !IsFastFullLine(*m_pCurTextFrame)
1801  || (!nTextPos && IsBlanksInString(*m_pCurTextFrame))
1802  || IsSentenceAtEnd(*m_pCurTextFrame);
1803 
1804  SetColl( static_cast<sal_uInt16>( nTextPos
1807 
1808  if( nTextPos )
1809  {
1810  const OUString& rStr = m_pCurTextFrame->GetText();
1811  bool bInsTab = true;
1812 
1813  if ('\t' == rStr[sal_Int32(nSpacePos) + 1]) // leave tab alone
1814  {
1815  --nSpacePos;
1816  bInsTab = false;
1817  }
1818 
1819  TextFrameIndex nSpaceStt = nSpacePos;
1820  while (nSpaceStt && IsSpace(rStr[sal_Int32(--nSpaceStt)]))
1821  ;
1822  ++nSpaceStt;
1823 
1824  if (bInsTab && '\t' == rStr[sal_Int32(nSpaceStt)]) // leave tab alone
1825  {
1826  ++nSpaceStt;
1827  bInsTab = false;
1828  }
1829 
1830  m_aDelPam.DeleteMark();
1831  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nSpacePos);
1832 
1833  // delete old Spaces, etc.
1834  if( nSpaceStt < nSpacePos )
1835  {
1836  m_aDelPam.SetMark();
1837  *m_aDelPam.GetMark() = m_pCurTextFrame->MapViewToModelPos(nSpaceStt);
1838  DeleteSel( m_aDelPam );
1839  if( bInsTab )
1840  {
1841  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString('\t') );
1842  }
1843  }
1844  }
1845 
1846  if( !bBreak )
1847  {
1849  SwTextFrameInfo aFInfo( m_pCurTextFrame );
1850  const SwTextFrame * pNextFrame = GetNextNode();
1851  while (CanJoin(pNextFrame) &&
1852  20 < std::abs( static_cast<long>(nSpaces - aFInfo.SetFrame(
1853  EnsureFormatted(*pNextFrame)).GetLineStart()) )
1854  )
1855  {
1856  bBreak = !IsFastFullLine(*pNextFrame)
1857  || IsBlanksInString(*pNextFrame)
1858  || IsSentenceAtEnd(*pNextFrame);
1859  if (DeleteJoinCurNextPara(pNextFrame))
1860  {
1861  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
1862  }
1863  if( bBreak )
1864  break;
1865  pNextFrame = GetNextNode();
1866  }
1867  }
1869  AutoCorrect();
1870 }
1871 
1872 void SwAutoFormat::BuildHeadLine( sal_uInt16 nLvl )
1873 {
1874  if( m_aFlags.bWithRedlining )
1875  {
1876  OUString sText(SwViewShell::GetShellRes()->GetAutoFormatNameLst()[
1878  sText = sText.replaceAll( "$(ARG1)", OUString::number( nLvl + 1 ) );
1880  }
1881 
1882  SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_HEADLINE1 + nLvl ), true );
1883  if( m_aFlags.bAFormatByInput )
1884  {
1885  SwTextFormatColl& rNxtColl = m_pCurTextFrame->GetTextNodeForParaProps()->GetTextColl()->GetNextTextFormatColl();
1886 
1887  JoinPrevPara();
1888 
1889  DeleteLeadingTrailingBlanks( true, false );
1890  const SwTextFrame *const pNextFrame = GetNextNode(false);
1891  (void)DeleteJoinCurNextPara(pNextFrame, true);
1892 
1893  m_aDelPam.DeleteMark();
1894  m_aDelPam.GetPoint()->nNode = *GetNextNode(false)->GetTextNodeForParaProps();
1895  m_aDelPam.GetPoint()->nContent.Assign( m_aDelPam.GetContentNode(), 0 );
1896  m_pDoc->SetTextFormatColl( m_aDelPam, &rNxtColl );
1897  }
1898  else
1899  {
1901  AutoCorrect();
1902  }
1903 }
1904 
1907 {
1909  ACFlags aSvxFlags = pATst->GetFlags( );
1910  bool bReplaceQuote( aSvxFlags & ACFlags::ChgQuotes );
1911  bool bReplaceSglQuote( aSvxFlags & ACFlags::ChgSglQuotes );
1912 
1913  if( m_aFlags.bAFormatByInput ||
1914  (!m_aFlags.bAutoCorrect && !bReplaceQuote && !bReplaceSglQuote &&
1915  !m_aFlags.bCapitalStartSentence && !m_aFlags.bCapitalStartWord &&
1916  !m_aFlags.bChgOrdinalNumber && !m_aFlags.bTransliterateRTL &&
1917  !m_aFlags.bChgToEnEmDash && !m_aFlags.bSetINetAttr &&
1918  !m_aFlags.bChgWeightUnderl && !m_aFlags.bAddNonBrkSpace) )
1919  return;
1920 
1921  const OUString* pText = &m_pCurTextFrame->GetText();
1922  if (TextFrameIndex(pText->getLength()) <= nPos)
1923  return;
1924 
1925  bool bGetLanguage = m_aFlags.bChgOrdinalNumber || m_aFlags.bTransliterateRTL ||
1926  m_aFlags.bChgToEnEmDash || m_aFlags.bSetINetAttr ||
1927  m_aFlags.bCapitalStartWord || m_aFlags.bCapitalStartSentence ||
1928  m_aFlags.bAddNonBrkSpace;
1929 
1930  m_aDelPam.DeleteMark();
1931  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
1932 
1933  SwAutoCorrDoc aACorrDoc( *m_pEditShell, m_aDelPam );
1934 
1935  SwTextFrameInfo aFInfo( nullptr );
1936 
1937  TextFrameIndex nSttPos, nLastBlank = nPos;
1938  bool bFirst = m_aFlags.bCapitalStartSentence, bFirstSent = bFirst;
1939  sal_Unicode cChar = 0;
1940  bool bNbspRunNext = false;
1941 
1942  CharClass& rAppCC = GetAppCharClass();
1943 
1944  do {
1945  while (nPos < TextFrameIndex(pText->getLength())
1946  && IsSpace(cChar = (*pText)[sal_Int32(nPos)]))
1947  ++nPos;
1948  if (nPos == TextFrameIndex(pText->getLength()))
1949  break; // that's it
1950 
1951  if( ( ( bReplaceQuote && '\"' == cChar ) ||
1952  ( bReplaceSglQuote && '\'' == cChar ) ) &&
1953  (!nPos || ' ' == (*pText)[sal_Int32(nPos)-1]))
1954  {
1955 
1956  // note: special case symbol fonts !!!
1957  if( !aFInfo.GetFrame() )
1958  aFInfo.SetFrame( GetFrame( *m_pCurTextNd ) );
1959  if( !aFInfo.IsBullet( nPos ))
1960  {
1962  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
1963  bool bSetHardBlank = false;
1964 
1965  OUString sReplace( pATst->GetQuote( aACorrDoc,
1966  sal_Int32(nPos), cChar, true ));
1967 
1968  m_aDelPam.SetMark();
1969  m_aDelPam.GetPoint()->nContent = m_aDelPam.GetMark()->nContent.GetIndex() + 1;
1970  if( 2 == sReplace.getLength() && ' ' == sReplace[ 1 ])
1971  {
1972  sReplace = sReplace.copy( 0, 1 );
1973  bSetHardBlank = true;
1974  }
1975  m_pDoc->getIDocumentContentOperations().ReplaceRange( m_aDelPam, sReplace, false );
1976 
1977  if( m_aFlags.bWithRedlining )
1978  {
1979  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
1980  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
1981  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
1982  pText = &m_pCurTextFrame->GetText();
1983  m_aDelPam.SetMark();
1984  aFInfo.SetFrame( nullptr );
1985  }
1986 
1987  nPos += TextFrameIndex(sReplace.getLength() - 1);
1988  m_aDelPam.DeleteMark();
1989  if( bSetHardBlank )
1990  {
1991  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(CHAR_HARDBLANK) );
1992  ++nPos;
1993  }
1994  }
1995  }
1996 
1997  bool bCallACorr = false;
1998  int bBreak = 0;
1999  if (nPos && IsSpace((*pText)[sal_Int32(nPos) - 1]))
2000  nLastBlank = nPos;
2001  for (nSttPos = nPos; !bBreak && nPos < TextFrameIndex(pText->getLength()); ++nPos)
2002  {
2003  cChar = (*pText)[sal_Int32(nPos)];
2004  switch (cChar)
2005  {
2006  case '\"':
2007  case '\'':
2008  if( ( cChar == '\"' && bReplaceQuote ) || ( cChar == '\'' && bReplaceSglQuote ) )
2009  {
2010  // consider Symbolfonts!
2011  if( !aFInfo.GetFrame() )
2012  aFInfo.SetFrame( GetFrame( *m_pCurTextNd ) );
2013  if( !aFInfo.IsBullet( nPos ))
2014  {
2016  bool bSetHardBlank = false;
2017  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
2018  OUString sReplace( pATst->GetQuote( aACorrDoc,
2019  sal_Int32(nPos), cChar, false) );
2020 
2021  if( 2 == sReplace.getLength() && ' ' == sReplace[ 0 ])
2022  {
2023  sReplace = sReplace.copy( 1 );
2024  bSetHardBlank = true;
2025  }
2026 
2027  m_aDelPam.SetMark();
2028  m_aDelPam.GetPoint()->nContent = m_aDelPam.GetMark()->nContent.GetIndex() + 1;
2029  m_pDoc->getIDocumentContentOperations().ReplaceRange( m_aDelPam, sReplace, false );
2030 
2031  if( m_aFlags.bWithRedlining )
2032  {
2033  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
2034  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
2035  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
2036  pText = &m_pCurTextFrame->GetText();
2037  m_aDelPam.SetMark();
2038  m_aDelPam.DeleteMark();
2039  aFInfo.SetFrame( nullptr );
2040  }
2041 
2042  nPos += TextFrameIndex(sReplace.getLength() - 1);
2043  m_aDelPam.DeleteMark();
2044 
2045  if( bSetHardBlank )
2046  {
2047  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
2048  m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(CHAR_HARDBLANK) );
2049  ++nPos;
2050  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
2051  }
2052  }
2053  }
2054  break;
2055  case '*':
2056  case '_':
2057  if( m_aFlags.bChgWeightUnderl )
2058  {
2059  // consider Symbolfonts!
2060  if( !aFInfo.GetFrame() )
2061  aFInfo.SetFrame( GetFrame( *m_pCurTextNd ) );
2062  if( !aFInfo.IsBullet( nPos ))
2063  {
2064  SetRedlineText( '*' == cChar
2067 
2068  sal_Unicode cBlank = nSttPos ? (*pText)[sal_Int32(nSttPos) - 1] : 0;
2069  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
2070 
2071  if (pATst->FnChgWeightUnderl(aACorrDoc, *pText, sal_Int32(nPos)))
2072  {
2073  if( m_aFlags.bWithRedlining )
2074  {
2075  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
2076  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
2077  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
2078  pText = &m_pCurTextFrame->GetText();
2079  m_aDelPam.SetMark();
2080  m_aDelPam.DeleteMark();
2081  aFInfo.SetFrame( nullptr );
2082  }
2083  //#125102# in case of the mode RedlineFlags::ShowDelete the ** are still contained in pText
2085  nPos = m_pCurTextFrame->MapModelToViewPos(*m_aDelPam.GetPoint()) - TextFrameIndex(1);
2086  // Was a character deleted before starting?
2087  if (cBlank && cBlank != (*pText)[sal_Int32(nSttPos) - 1])
2088  --nSttPos;
2089  }
2090  }
2091  }
2092  break;
2093  case '/':
2094  if ( m_aFlags.bAddNonBrkSpace )
2095  {
2096  LanguageType eLang = bGetLanguage
2097  ? m_pCurTextFrame->GetLangOfChar(nSttPos, 0, true)
2098  : LANGUAGE_SYSTEM;
2099 
2101  if (pATst->FnAddNonBrkSpace(aACorrDoc, *pText, sal_Int32(nPos), eLang, bNbspRunNext))
2102  --nPos;
2103  }
2104  break;
2105 
2106  case '.':
2107  case '!':
2108  case '?':
2109  if( m_aFlags.bCapitalStartSentence )
2110  bFirstSent = true;
2111  [[fallthrough]];
2112  default:
2113  if (!(rAppCC.isLetterNumeric(*pText, sal_Int32(nPos))
2114  || '/' == cChar )) // '/' should not be a word separator (e.g. '1/2' needs to be handled as one word for replacement)
2115  {
2116  --nPos; // revert ++nPos which was decremented in for loop
2117  ++bBreak;
2118  }
2119  break;
2120  }
2121  }
2122 
2123  if( nPos == nSttPos )
2124  {
2125  if (++nPos == TextFrameIndex(pText->getLength()))
2126  bCallACorr = true;
2127  }
2128  else
2129  bCallACorr = true;
2130 
2131  if( bCallACorr )
2132  {
2133  *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(nPos);
2135  if( m_aFlags.bAutoCorrect &&
2136  aACorrDoc.ChgAutoCorrWord(reinterpret_cast<sal_Int32&>(nSttPos), sal_Int32(nPos), *pATst, nullptr))
2137  {
2138  nPos = m_pCurTextFrame->MapModelToViewPos(*m_aDelPam.GetPoint());
2139 
2140  if( m_aFlags.bWithRedlining )
2141  {
2142  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
2143  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
2144  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
2145  pText = &m_pCurTextFrame->GetText();
2146  m_aDelPam.SetMark();
2147  m_aDelPam.DeleteMark();
2148  }
2149 
2150  continue; // do not check further
2151  }
2152 
2153  LanguageType eLang = bGetLanguage
2154  ? m_pCurTextFrame->GetLangOfChar(nSttPos, 0, true)
2155  : LANGUAGE_SYSTEM;
2156 
2157  if( m_aFlags.bTransliterateRTL && eLang == LANGUAGE_HUNGARIAN &&
2159  aACorrDoc.TransliterateRTLWord(reinterpret_cast<sal_Int32&>(nSttPos), sal_Int32(nPos)))
2160  {
2161  nPos = m_pCurTextFrame->MapModelToViewPos(*m_aDelPam.GetPoint());
2162  if( m_aFlags.bWithRedlining )
2163  {
2164  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
2165  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
2166  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
2167  pText = &m_pCurTextFrame->GetText();
2168  m_aDelPam.SetMark();
2169  m_aDelPam.DeleteMark();
2170  }
2171 
2172  continue; // do not check further
2173  }
2174 
2175  if ( m_aFlags.bAddNonBrkSpace )
2176  {
2178  pATst->FnAddNonBrkSpace(aACorrDoc, *pText, sal_Int32(nPos), eLang, bNbspRunNext);
2179  }
2180 
2181  if( ( m_aFlags.bChgOrdinalNumber &&
2183  pATst->FnChgOrdinalNumber(aACorrDoc, *pText, sal_Int32(nSttPos), sal_Int32(nPos), eLang)) ||
2184  ( m_aFlags.bChgToEnEmDash &&
2186  pATst->FnChgToEnEmDash(aACorrDoc, *pText, sal_Int32(nSttPos), sal_Int32(nPos), eLang)) ||
2187  ( m_aFlags.bSetINetAttr &&
2188  (nPos == TextFrameIndex(pText->getLength()) || IsSpace((*pText)[sal_Int32(nPos)])) &&
2190  pATst->FnSetINetAttr(aACorrDoc, *pText, sal_Int32(nLastBlank), sal_Int32(nPos), eLang)))
2191  {
2192  nPos = m_pCurTextFrame->MapModelToViewPos(*m_aDelPam.GetPoint());
2193  }
2194  else
2195  {
2196  // two capital letters at the beginning of a word?
2197  if( m_aFlags.bCapitalStartWord )
2198  {
2200  pATst->FnCapitalStartWord(aACorrDoc, *pText, sal_Int32(nSttPos), sal_Int32(nPos), eLang);
2201  }
2202  // capital letter at the beginning of a sentence?
2203  if( m_aFlags.bCapitalStartSentence && bFirst )
2204  {
2206  pATst->FnCapitalStartSentence(aACorrDoc, *pText, true, sal_Int32(nSttPos), sal_Int32(nPos), eLang);
2207  }
2208 
2209  bFirst = bFirstSent;
2210  bFirstSent = false;
2211 
2212  if( m_aFlags.bWithRedlining )
2213  {
2214  m_aNdIdx = m_aDelPam.GetPoint()->nNode;
2215  m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
2216  m_pCurTextFrame = GetFrame( *m_pCurTextNd );
2217  pText = &m_pCurTextFrame->GetText();
2218  m_aDelPam.SetMark();
2219  m_aDelPam.DeleteMark();
2220  }
2221  }
2222  }
2223  }
2224  while (nPos < TextFrameIndex(pText->getLength()));
2225  ClearRedlineText();
2226 }
2227 
2229  SwNodeIndex const * pSttNd, SwNodeIndex const * pEndNd )
2230  : m_aFlags( rFlags ),
2231  m_aDelPam( pEdShell->GetDoc()->GetNodes().GetEndOfExtras() ),
2232  m_aNdIdx( pEdShell->GetDoc()->GetNodes().GetEndOfExtras(), +1 ),
2233  m_aEndNdIdx( pEdShell->GetDoc()->GetNodes().GetEndOfContent() ),
2234  m_pEditShell( pEdShell ),
2235  m_pDoc( pEdShell->GetDoc() ),
2236  m_pCurTextNd( nullptr ), m_pCurTextFrame( nullptr ),
2237  m_nRedlAutoFormatSeqId( 0 )
2238 {
2239  OSL_ENSURE( (pSttNd && pEndNd) || (!pSttNd && !pEndNd),
2240  "Got no area" );
2241 
2242  if( m_aFlags.bSetNumRule && !m_aFlags.bAFormatByInput )
2243  m_aFlags.bSetNumRule = false;
2244 
2245  bool bReplaceStyles = !m_aFlags.bAFormatByInput || m_aFlags.bReplaceStyles;
2246 
2247  const SwTextFrame * pNextFrame = nullptr;
2248  bool bNxtEmpty = false;
2249  bool bNxtAlpha = false;
2250  sal_uInt16 nNxtLevel = 0;
2251  bool bEmptyLine;
2252 
2253  // set area for autoformatting
2254  if( pSttNd )
2255  {
2256  m_aNdIdx = *pSttNd;
2257  // for GoNextPara, one paragraph prior to that
2258  sw::GotoPrevLayoutTextFrame(m_aNdIdx, m_pEditShell->GetLayout());
2259  m_aEndNdIdx = *pEndNd;
2260  sw::GotoNextLayoutTextFrame(m_aEndNdIdx, m_pEditShell->GetLayout());
2261 
2262  // check the previous TextNode
2263  SwTextFrame const*const pPrevFrame = m_aNdIdx.GetNode().GetTextNode()
2264  ? static_cast<SwTextFrame const*>(m_aNdIdx.GetNode().GetTextNode()->getLayoutFrame(m_pEditShell->GetLayout()))
2265  : nullptr;
2266  bEmptyLine = !pPrevFrame
2267  || IsEmptyLine(*pPrevFrame)
2268  || IsNoAlphaLine(*pPrevFrame);
2269  }
2270  else
2271  bEmptyLine = true; // at document beginning
2272 
2273  m_bEnd = false;
2274 
2275  // set value for percentage display
2276  m_nEndNdIdx = m_aEndNdIdx.GetIndex();
2277 
2278  if( !m_aFlags.bAFormatByInput )
2279  {
2280  m_nEndNdIdx = m_aEndNdIdx.GetIndex();
2281  ::StartProgress( STR_STATSTR_AUTOFORMAT, m_aNdIdx.GetIndex(),
2282  m_nEndNdIdx,
2283  m_pDoc->GetDocShell() );
2284  }
2285 
2286  RedlineFlags eRedlMode = m_pDoc->getIDocumentRedlineAccess().GetRedlineFlags(), eOldMode = eRedlMode;
2287  if( m_aFlags.bWithRedlining )
2288  {
2289  m_pDoc->SetAutoFormatRedline( true );
2290  eRedlMode = RedlineFlags::On | (eOldMode & RedlineFlags::ShowMask);
2291  }
2292  else
2293  eRedlMode = RedlineFlags::Ignore | (eOldMode & RedlineFlags::ShowMask);
2294  m_pDoc->getIDocumentRedlineAccess().SetRedlineFlags( eRedlMode );
2295 
2296  // save undo state (might be turned off)
2297  bool const bUndoState = m_pDoc->GetIDocumentUndoRedo().DoesUndo();
2298 
2299  // If multiple lines, then do not merge with next paragraph
2300  m_bMoreLines = false;
2301 
2302  sal_uInt16 nLastCalcHeadLvl = 0;
2303  sal_uInt16 nLastHeadLvl = USHRT_MAX;
2304  sal_uInt16 nLevel = 0;
2305  sal_uInt16 nDigitLvl = 0;
2306 
2307  // set defaults
2308  SwTextFrameInfo aFInfo( nullptr );
2309 
2310  enum Format_Status
2311  {
2312  READ_NEXT_PARA, // -> ISEND, TST_EMPTY_LINE
2313  TST_EMPTY_LINE, // -> READ_NEXT_PARA, TST_ALPHA_LINE
2314  TST_ALPHA_LINE, // -> READ_NEXT_PARA, GET_ALL_INFO, IS_END
2315  GET_ALL_INFO, // -> READ_NEXT_PARA, IS_ONE_LINE, TST_ENUMERIC, HAS_FMTCOLL
2316  IS_ONE_LINE, // -> READ_NEXT_PARA, TST_ENUMERIC
2317  TST_ENUMERIC, // -> READ_NEXT_PARA, TST_IDENT, TST_NEG_IDENT
2318  TST_IDENT, // -> READ_NEXT_PARA, TST_TXT_BODY
2319  TST_NEG_IDENT, // -> READ_NEXT_PARA, TST_TXT_BODY
2320  TST_TXT_BODY, // -> READ_NEXT_PARA
2321  HAS_FMTCOLL, // -> READ_NEXT_PARA
2322  IS_END
2323  } eStat;
2324 
2325  // This is the automat for autoformatting
2326  eStat = READ_NEXT_PARA;
2327  while( !m_bEnd )
2328  {
2329  switch( eStat )
2330  {
2331  case READ_NEXT_PARA:
2332  {
2333  GoNextPara();
2334  eStat = m_bEnd ? IS_END : TST_EMPTY_LINE;
2335  }
2336  break;
2337 
2338  case TST_EMPTY_LINE:
2339  if (IsEmptyLine(*m_pCurTextFrame))
2340  {
2341  if (m_aFlags.bDelEmptyNode && !HasObjects(*m_pCurTextFrame))
2342  {
2343  bEmptyLine = true;
2344  sal_uLong nOldCnt = m_pDoc->GetNodes().Count();
2345  DelEmptyLine();
2346  // Was there really a deletion of a node?
2347  if( nOldCnt != m_pDoc->GetNodes().Count() )
2348  {
2349  // do not skip the next paragraph
2350  sw::GotoPrevLayoutTextFrame(m_aNdIdx, m_pEditShell->GetLayout());
2351  }
2352  }
2353  eStat = READ_NEXT_PARA;
2354  }
2355  else
2356  eStat = TST_ALPHA_LINE;
2357  break;
2358 
2359  case TST_ALPHA_LINE:
2360  if (IsNoAlphaLine(*m_pCurTextFrame))
2361  {
2362  // recognize a table definition +---+---+
2363  if( m_aFlags.bAFormatByInput && m_aFlags.bCreateTable && DoTable() )
2364  {
2365  //JP 30.09.96: DoTable() builds on PopCursor and MoveCursor after AutoFormat!
2367  *pEdShell->GetCursor() = m_aDelPam;
2368  pEdShell->Push();
2369 
2370  eStat = IS_END;
2371  break;
2372  }
2373 
2374  // Check for 3 "---" or "===". In this case, the previous paragraph should be
2375  // underlined and the current be deleted!
2376  if( !DoUnderline() && bReplaceStyles )
2377  {
2378  SetColl( RES_POOLCOLL_STANDARD, true );
2379  bEmptyLine = true;
2380  }
2381  eStat = READ_NEXT_PARA;
2382  }
2383  else
2384  eStat = GET_ALL_INFO;
2385  break;
2386 
2387  case GET_ALL_INFO:
2388  {
2389  if (m_pCurTextFrame->GetTextNodeForParaProps()->GetNumRule())
2390  {
2391  // do nothing in numbering, go to next
2392  bEmptyLine = false;
2393  eStat = READ_NEXT_PARA;
2394  // delete all blanks at beginning/end and in between
2395  //JP 29.04.98: first only "all in between"
2397  break;
2398  }
2399 
2400  aFInfo.SetFrame( m_pCurTextFrame );
2401 
2402  // so far: if there were templates assigned, keep these and go to next node
2403  sal_uInt16 nPoolId = m_pCurTextFrame->GetTextNodeForParaProps()->GetTextColl()->GetPoolFormatId();
2404  if( IsPoolUserFormat( nPoolId )
2405  ? !m_aFlags.bChgUserColl
2406  : ( RES_POOLCOLL_STANDARD != nPoolId &&
2407  ( !m_aFlags.bAFormatByInput ||
2408  (RES_POOLCOLL_TEXT_MOVE != nPoolId &&
2409  RES_POOLCOLL_TEXT != nPoolId )) ))
2410  {
2411  eStat = HAS_FMTCOLL;
2412  break;
2413  }
2414 
2415  // check for hard spaces or LRSpaces set by the template
2416  if( IsPoolUserFormat( nPoolId ) ||
2417  RES_POOLCOLL_STANDARD == nPoolId )
2418  {
2419  short nSz;
2420  SvxLRSpaceItem const * pLRSpace;
2421  if (SfxItemState::SET == m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().
2422  GetItemState( RES_LR_SPACE, true,
2423  reinterpret_cast<const SfxPoolItem**>(&pLRSpace) ) &&
2424  ( 0 != (nSz = pLRSpace->GetTextFirstLineOffset()) ||
2425  0 != pLRSpace->GetTextLeft() ) )
2426  {
2427  // exception: numbering/enumeration can have an indentation
2428  if (IsEnumericChar(*m_pCurTextFrame))
2429  {
2430  nLevel = CalcLevel(*m_pCurTextFrame, &nDigitLvl);
2431  if( nLevel >= MAXLEVEL )
2432  nLevel = MAXLEVEL-1;
2433  BuildEnum( nLevel, nDigitLvl );
2434  eStat = READ_NEXT_PARA;
2435  break;
2436  }
2437 
2438  // never merge (maybe only indent as exception)
2439  m_bMoreLines = true;
2440 
2441  if( bReplaceStyles )
2442  {
2443  // then use one of our templates
2444  if( 0 < nSz ) // positive 1st line indentation
2445  BuildIndent();
2446  else if( 0 > nSz ) // negative 1st line indentation
2447  BuildNegIndent( aFInfo.GetLineStart() );
2448  else if( pLRSpace->GetTextLeft() ) // is indentation
2449  BuildTextIndent();
2450  }
2451  eStat = READ_NEXT_PARA;
2452  break;
2453  }
2454  }
2455 
2456  nLevel = CalcLevel( *m_pCurTextFrame, &nDigitLvl );
2457  m_bMoreLines = !IsOneLine(*m_pCurTextFrame);
2458  // note: every use of pNextFrame in following states, until the
2459  // next READ_NEXT_PARA, relies on this update
2460  pNextFrame = GetNextNode();
2461  if (pNextFrame)
2462  {
2463  bNxtEmpty = IsEmptyLine(*pNextFrame);
2464  bNxtAlpha = IsNoAlphaLine(*pNextFrame);
2465  nNxtLevel = CalcLevel(*pNextFrame);
2466 
2467  if (!bEmptyLine && HasBreakAttr(*m_pCurTextFrame))
2468  bEmptyLine = true;
2469  if (!bNxtEmpty && HasBreakAttr(*pNextFrame))
2470  bNxtEmpty = true;
2471 
2472  }
2473  else
2474  {
2475  bNxtEmpty = false;
2476  bNxtAlpha = false;
2477  nNxtLevel = 0;
2478  }
2479  eStat = !m_bMoreLines ? IS_ONE_LINE : TST_ENUMERIC;
2480  }
2481  break;
2482 
2483  case IS_ONE_LINE:
2484  {
2485  eStat = TST_ENUMERIC;
2486  if( !bReplaceStyles )
2487  break;
2488 
2489  const OUString sClrStr( DelLeadingBlanks(m_pCurTextFrame->GetText()) );
2490 
2491  if( sClrStr.isEmpty() )
2492  {
2493  bEmptyLine = true;
2494  eStat = READ_NEXT_PARA;
2495  break; // read next paragraph
2496  }
2497 
2498  // check if headline
2499  if (!bEmptyLine || !IsFirstCharCapital(*m_pCurTextFrame)
2500  || IsBlanksInString(*m_pCurTextFrame))
2501  break;
2502 
2503  bEmptyLine = false;
2504  const OUString sEndClrStr( DelTrailingBlanks(sClrStr) );
2505  const sal_Unicode cLast = sEndClrStr[sEndClrStr.getLength() - 1];
2506 
2507  // not, then check if headline
2508  if( ':' == cLast )
2509  {
2510  BuildHeadLine( 2 );
2511  eStat = READ_NEXT_PARA;
2512  break;
2513  }
2514  else if( 256 <= cLast || !strchr( ",.;", cLast ) )
2515  {
2516  if( bNxtEmpty || bNxtAlpha
2517  || (pNextFrame && IsEnumericChar(*pNextFrame)))
2518  {
2519 
2520  // one level below?
2521  if( nLevel >= MAXLEVEL )
2522  nLevel = MAXLEVEL-1;
2523 
2524  if( USHRT_MAX == nLastHeadLvl )
2525  nLastHeadLvl = 0;
2526  else if( nLastCalcHeadLvl < nLevel )
2527  {
2528  if( nLastHeadLvl+1 < MAXLEVEL )
2529  ++nLastHeadLvl;
2530  }
2531  // one level above?
2532  else if( nLastCalcHeadLvl > nLevel )
2533  {
2534  if( nLastHeadLvl )
2535  --nLastHeadLvl;
2536  }
2537  nLastCalcHeadLvl = nLevel;
2538 
2539  if( m_aFlags.bAFormatByInput )
2540  BuildHeadLine( nLevel );
2541  else
2542  BuildHeadLine( nLastHeadLvl );
2543  eStat = READ_NEXT_PARA;
2544  break;
2545  }
2546  }
2547  }
2548  break;
2549 
2550  case TST_ENUMERIC:
2551  {
2552  bEmptyLine = false;
2553  if (IsEnumericChar(*m_pCurTextFrame))
2554  {
2555  if( nLevel >= MAXLEVEL )
2556  nLevel = MAXLEVEL-1;
2557  BuildEnum( nLevel, nDigitLvl );
2558  eStat = READ_NEXT_PARA;
2559  }
2560  else if( bReplaceStyles )
2561  eStat = nLevel ? TST_IDENT : TST_NEG_IDENT;
2562  else
2563  eStat = READ_NEXT_PARA;
2564  }
2565  break;
2566 
2567  case TST_IDENT:
2568  // Spaces at the beginning, check again for indentation
2569  if( m_bMoreLines && nLevel )
2570  {
2571  SwTwips nSz = aFInfo.GetFirstIndent();
2572  if( 0 < nSz ) // positive 1st line indentation
2573  BuildIndent();
2574  else if( 0 > nSz ) // negative 1st line indentation
2575  BuildNegIndent( aFInfo.GetLineStart() );
2576  else // is indentation
2577  BuildTextIndent();
2578  eStat = READ_NEXT_PARA;
2579  }
2580  else if (nLevel && pNextFrame &&
2581  !bNxtEmpty && !bNxtAlpha && !nNxtLevel &&
2582  !IsEnumericChar(*pNextFrame))
2583  {
2584  // is an indentation
2585  BuildIndent();
2586  eStat = READ_NEXT_PARA;
2587  }
2588  else
2589  eStat = TST_TXT_BODY;
2590  break;
2591 
2592  case TST_NEG_IDENT:
2593  // no spaces at the beginning, check again for negative indentation
2594  {
2595  if( m_bMoreLines && !nLevel )
2596  {
2597  SwTwips nSz = aFInfo.GetFirstIndent();
2598  if( 0 < nSz ) // positive 1st line indentation
2599  BuildIndent();
2600  else if( 0 > nSz ) // negative 1st line indentation
2601  BuildNegIndent( aFInfo.GetLineStart() );
2602  else // is _no_ indentation
2603  BuildText();
2604  eStat = READ_NEXT_PARA;
2605  }
2606  else if (!nLevel && pNextFrame &&
2607  !bNxtEmpty && !bNxtAlpha && nNxtLevel &&
2608  !IsEnumericChar(*pNextFrame))
2609  {
2610  // is a negative indentation
2611  BuildNegIndent( aFInfo.GetLineStart() );
2612  eStat = READ_NEXT_PARA;
2613  }
2614  else
2615  eStat = TST_TXT_BODY;
2616  }
2617  break;
2618 
2619  case TST_TXT_BODY:
2620  {
2621  if( m_bMoreLines )
2622  {
2623  SwTwips nSz = aFInfo.GetFirstIndent();
2624  if( 0 < nSz ) // positive 1st line indentation
2625  BuildIndent();
2626  else if( 0 > nSz ) // negative 1st line indentation
2627  BuildNegIndent( aFInfo.GetLineStart() );
2628  else if( nLevel ) // is indentation
2629  BuildTextIndent();
2630  else
2631  BuildText();
2632  }
2633  else if( nLevel )
2634  BuildTextIndent();
2635  else
2636  BuildText();
2637  eStat = READ_NEXT_PARA;
2638  }
2639  break;
2640 
2641  case HAS_FMTCOLL:
2642  {
2643  // so far: if there were templates assigned, keep these and go to next node
2644  bEmptyLine = false;
2645  eStat = READ_NEXT_PARA;
2646  // delete all blanks at beginning/end and in between
2647  //JP 29.04.98: first only "all in between"
2649 
2650  // handle hard attributes
2651  if (m_pCurTextFrame->GetTextNodeForParaProps()->HasSwAttrSet())
2652  {
2653  short nSz;
2654  SvxLRSpaceItem const * pLRSpace;
2655  if( bReplaceStyles &&
2656  SfxItemState::SET == m_pCurTextFrame->GetTextNodeForParaProps()->GetSwAttrSet().
2657  GetItemState( RES_LR_SPACE, false,
2658  reinterpret_cast<const SfxPoolItem**>(&pLRSpace) ) &&
2659  ( 0 != (nSz = pLRSpace->GetTextFirstLineOffset()) ||
2660  0 != pLRSpace->GetTextLeft() ) )
2661  {
2662  // then use one of our templates
2663  if( 0 < nSz ) // positive 1st line indentation
2664  BuildIndent();
2665  else if( 0 > nSz ) // negative 1st line indentation
2666  {
2667  BuildNegIndent( aFInfo.GetLineStart() );
2668  }
2669  else if( pLRSpace->GetTextLeft() ) // is indentation
2670  BuildTextIndent();
2671  else
2672  BuildText();
2673  }
2674  }
2675  }
2676  break;
2677 
2678  case IS_END:
2679  m_bEnd = true;
2680  break;
2681  }
2682  }
2683 
2684  if( m_aFlags.bWithRedlining )
2685  m_pDoc->SetAutoFormatRedline( false );
2686  m_pDoc->getIDocumentRedlineAccess().SetRedlineFlags( eOldMode );
2687 
2688  // restore undo (in case it has been changed)
2689  m_pDoc->GetIDocumentUndoRedo().DoUndo(bUndoState);
2690 
2691  // disable display of percentage again
2692  if( !m_aFlags.bAFormatByInput )
2693  ::EndProgress( m_pDoc->GetDocShell() );
2694 }
2695 
2697 {
2698  std::unique_ptr<SwWait> pWait;
2699 
2700  CurrShell aCurr( this );
2701  StartAllAction();
2703 
2704  SvxSwAutoFormatFlags aAFFlags; // use default values or add params?
2705  if( pAFlags )
2706  {
2707  aAFFlags = *pAFlags;
2708  if( !aAFFlags.bAFormatByInput )
2709  pWait.reset(new SwWait( *GetDoc()->GetDocShell(), true ));
2710  }
2711 
2712  SwPaM* pCursor = GetCursor();
2713  // There are more than one or a selection is open
2714  if( pCursor->GetNext() != pCursor || pCursor->HasMark() )
2715  {
2716  for(SwPaM& rPaM : GetCursor()->GetRingContainer())
2717  {
2718  if( rPaM.HasMark() )
2719  {
2720  SwAutoFormat aFormat( this, aAFFlags, &(rPaM.Start()->nNode),
2721  &(rPaM.End()->nNode) );
2722  }
2723  }
2724  }
2725  else
2726  {
2727  SwAutoFormat aFormat( this, aAFFlags );
2728  }
2729 
2731  EndAllAction();
2732 }
2733 
2735 {
2736  CurrShell aCurr( this );
2737  SwPaM* pCursor = GetCursor();
2738  if( pCursor->IsMultiSelection() || !pCursor->Move( fnMoveBackward, GoInNode ) )
2739  return;
2740 
2741  StartAllAction();
2743 
2744  bool bRange = false;
2745  pCursor->SetMark();
2746  SwIndex* pContent = &pCursor->GetMark()->nContent;
2747  if( pContent->GetIndex() )
2748  {
2749  *pContent = 0;
2750  bRange = true;
2751  }
2752  else
2753  {
2754  // then go one node backwards
2755  SwNodeIndex aNdIdx(pCursor->GetMark()->nNode);
2757  SwTextNode* pTextNd = aNdIdx.GetNode().GetTextNode();
2758  if (pTextNd && !pTextNd->GetText().isEmpty())
2759  {
2760  pContent->Assign( pTextNd, 0 );
2761  pCursor->GetMark()->nNode = aNdIdx;
2762  bRange = true;
2763  }
2764  }
2765 
2766  if( bRange )
2767  {
2768  Push(); // save cursor
2769 
2770  SvxSwAutoFormatFlags aAFFlags = *GetAutoFormatFlags(); // use default values so far
2771 
2772  SwAutoFormat aFormat( this, aAFFlags, &pCursor->GetMark()->nNode,
2773  &pCursor->GetPoint()->nNode );
2775  if( pACorr && !pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord |
2776  ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL |
2777  ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | ACFlags::Autocorrect ))
2778  pACorr = nullptr;
2779 
2780  if( pACorr )
2781  AutoCorrect( *pACorr,false, u'\0' );
2782 
2783  //JP 30.09.96: DoTable() builds on PopCursor and MoveCursor!
2785  pCursor = GetCursor();
2786  }
2787  pCursor->DeleteMark();
2788  pCursor->Move( fnMoveForward, GoInNode );
2789 
2791  EndAllAction();
2792 
2793 }
2794 
2796 {
2797  if (!s_pAutoFormatFlags)
2799 
2800  return s_pAutoFormatFlags;
2801 }
2802 
2804 {
2805  SvxSwAutoFormatFlags* pEditFlags = GetAutoFormatFlags();
2806 
2807  pEditFlags->bSetNumRule = pFlags->bSetNumRule;
2808  pEditFlags->bChgEnumNum = pFlags->bChgEnumNum;
2809  pEditFlags->bSetBorder = pFlags->bSetBorder;
2810  pEditFlags->bCreateTable = pFlags->bCreateTable;
2811  pEditFlags->bReplaceStyles = pFlags->bReplaceStyles;
2812  pEditFlags->bAFormatByInpDelSpacesAtSttEnd =
2816 
2817  //JP 15.12.98: copy BulletChar and Font into "normal" ones
2818  // because AutoFormat can only work with the latter!
2819  pEditFlags->cBullet = pFlags->cByInputBullet;
2820  pEditFlags->aBulletFont = pFlags->aByInputBulletFont;
2821  pEditFlags->cByInputBullet = pFlags->cByInputBullet;
2822  pEditFlags->aByInputBulletFont = pFlags->aByInputBulletFont;
2823 }
2824 
2825 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual SwCharFormat * GetCharFormatFromPool(sal_uInt16 nId)=0
long GetLeft() const
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:339
static SwTwips GetLineStart(const SwTextCursor &rLine)
Definition: frminf.cxx:89
void AutoCorrect(TextFrameIndex nSttPos=TextFrameIndex(0))
execute AutoCorrect on current TextNode
Definition: autofmt.cxx:1906
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
void merge(RingContainer< value_type > aDestRing)
Merges two ring containers.
Definition: ring.hxx:182
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
std::shared_ptr< SwUnoCursor > CreateUnoCursor(const SwPosition &rPos, bool bTableCursor=false)
Definition: doc.cxx:1778
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:282
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
sal_uLong Count() const
Definition: ndarr.hxx:142
bool FnChgToEnEmDash(SvxAutoCorrDoc &, const OUString &, sal_Int32 nSttPos, sal_Int32 nEndPos, LanguageType eLang)
bool bAFormatByInpDelSpacesBetweenLines
sal_Int32 getCharacterType(const OUString &rStr, sal_Int32 nPos) const
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
static OUString DelTrailingBlanks(const OUString &rStr)
Definition: autofmt.cxx: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:644
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:189
SvxAdjust GetAdjust() const
LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, bool bNoChar=false) const
Definition: txtfrm.cxx:1333
#define STR_AUTOFMTREDL_NON_BREAK_SPACE
Definition: comcore.hxx:44
const OUString & GetText() const
Definition: ndtxt.hxx:211
static ShellResource * GetShellRes()
Definition: viewsh.cxx:2485
void SetColl(sal_uInt16 nId, bool bHdLineOrText=false)
Definition: autofmt.cxx:999
SwDocShell * GetDocShell()
Definition: doc.hxx:1348
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)
sal_uInt16 const aTextNodeSetRange[]
Definition: init.cxx:170
void BuildTextIndent()
Definition: autofmt.cxx:1382
SwNodeIndex nNode
Definition: pam.hxx:37
void SetCompletePaint() const
Definition: frame.hxx:972
virtual void InsertItemSet(const SwPaM &rRg, const SfxItemSet &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr)=0
void ClearRedlineText()
Definition: autofmt.cxx:212
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:178
const SwPosition * GetMark() const
Definition: pam.hxx:209
void SetPrefix(const OUString &rSet)
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:399
SVX_NUM_CHARS_UPPER_LETTER
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:441
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1190
sal_Int64 n
Definition: doc.hxx:184
helper class to disable creation of an action by a callback event in particular, change event from a ...
Definition: rootfrm.hxx:441
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:168
bool IsPoolUserFormat(sal_uInt16 nId)
Definition: poolfmt.hxx:87
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
void DeleteSel(SwPaM &rPam)
Definition: autofmt.cxx:1164
constexpr TypedWhichId< SvxFormatBreakItem > RES_BREAK(94)
static bool HasObjects(const SwTextFrame &)
Definition: autofmt.cxx:340
::sw::DocumentRedlineManager const & GetDocumentRedlineManager() const
Definition: doc.cxx:344
SwDoc * m_pDoc
Definition: autofmt.cxx:93
SwNode & GetNode() const
Definition: ndindex.hxx:119
long SwTwips
Definition: swtypes.hxx:49
static bool HasSelBlanks(SwTextFrame const *const pStartFrame, TextFrameIndex &rStartIndex, SwTextFrame const *const pEndFrame, TextFrameIndex &rEndIndex)
Definition: autofmt.cxx:1033
void EndProgress(SwDocShell const *pDocShell)
Definition: mainwn.cxx:92
OUString GetUniqueNumRuleName(const OUString *pChkStr=nullptr, bool bAutoNum=true) const
Definition: docnum.cxx:2494
Dialog to specify the properties of date form field.
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:143
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1787
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void SetIncludeUpperLevels(sal_uInt8 nSet)
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1283
SwTextFrame * EnsureFormatted(SwTextFrame const &) const
Definition: autofmt.cxx:237
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:314
sal_Int32 GetBigIndent(TextFrameIndex &rFndPos, const SwTextFrame *pNextFrame) const
Definition: frminf.cxx: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:169
#define DEF_LINE_WIDTH_1
#define LANGUAGE_HUNGARIAN
FontFamily GetFamilyType()
const SwSection & GetSection() const
Definition: node.hxx:541
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
bool bAFormatByInpDelSpacesAtSttEnd
const sal_Unicode cStarSymbolEmDash
Definition: autofmt.cxx:77
#define STR_AUTOFMTREDL_DEL_MORELINES
Definition: comcore.hxx:43
void FnCapitalStartSentence(SvxAutoCorrDoc &, const OUString &, bool bNormalPos, sal_Int32 nSttPos, sal_Int32 nEndPos, LanguageType eLang)
bool isLetterNumeric(const OUString &rStr, sal_Int32 nPos) const
sal_uInt16 sal_Unicode
#define STR_AUTOFMTREDL_CPTL_STT_WORD
Definition: comcore.hxx:25
void SetRedlineText_(sal_uInt16 nId)
Definition: autofmt.cxx:257
void JoinPrevPara()
join with the previous paragraph
Definition: autofmt.cxx:1325
bool IsBullet(TextFrameIndex nTextPos) const
Definition: frminf.cxx:195
ACFlags
void StartProgress(const char *pMessResId, long nStartValue, long nEndValue, SwDocShell *pDocShell)
Definition: mainwn.cxx:52
SwIndex nContent
Definition: pam.hxx:38
const SwRect & getFrameArea() const
Definition: frame.hxx:177
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
#define STR_AUTOFMTREDL_USE_REPLACE
Definition: comcore.hxx:24
bool CanJoin(const SwTextFrame *pNextFrame) const
Definition: autofmt.cxx:186
bool SetTextFormatColl(const SwPaM &rRg, SwTextFormatColl *pFormat, const bool bReset=true, const bool bResetListAttrs=false, SwRootFrame const *pLayout=nullptr)
Add 4th optional parameter .
Definition: docfmt.cxx:1072
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:425
#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:39
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:293
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
virtual void DoUndo(bool const bDoUndo)=0
Enable/Disable Undo.
For internal use only.
sal_uInt16 GetDigitLevel(const SwTextFrame &rFrame, TextFrameIndex &rPos, OUString *pPrefix=nullptr, OUString *pPostfix=nullptr, OUString *pNumTypes=nullptr) const
Definition: autofmt.cxx:750
SVX_NUM_ROMAN_UPPER
void SetFormatItemByAutoFormat(const SwPaM &rPam, const SfxItemSet &)
Definition: docfmt.cxx:1807
sal_uInt8 GetAutoFormatLvl() const
Definition: node.hxx:138
std::unique_ptr< CharClass > m_pCharClass
Definition: autofmt.cxx:97
void DelMoreLinesBlanks(bool bWithLineBreaks=false)
when using multiline paragraphs delete the "left" and/or "right" margins
Definition: autofmt.cxx:1288
#define STR_AUTOFMTREDL_SET_TMPL_TEXT
Definition: comcore.hxx:37
Numbering symbols.
Definition: poolfmt.hxx:118
SVX_NUM_ROMAN_LOWER
bool IsProtectFlag() const
Definition: section.hxx:188
SwDoc * GetDoc() const
Definition: viewsh.hxx:282
void GotoNextLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1474
Text body indent.
Definition: poolfmt.hxx:254
RedlineFlags on.
bool IsEmpty() const
Definition: swrect.hxx:292
virtual bool DoesUndo() const =0
Is Undo enabled?
void BuildEnum(sal_uInt16 nLvl, sal_uInt16 nDigitLevel)
Definition: autofmt.cxx:1462
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:143
void SetProgressState(long nPosition, SwDocShell const *pDocShell)
Definition: mainwn.cxx:82
void FnCapitalStartWord(SvxAutoCorrDoc &, const OUString &, sal_Int32 nSttPos, sal_Int32 nEndPos, LanguageType eLang)
LanguageType m_eCharClassLang
Definition: autofmt.cxx:98
SwRect GetPaintSwRect()
Page number etc.
Definition: frmpaint.cxx:410
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:328
const short lBulletIndent
Definition: swtypes.hxx:107
SVX_NUM_CHAR_SPECIAL
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:448
const SwTextFrame * GetNextNode(bool isCheckEnd=true) const
Definition: autofmt.cxx:358
bool FrameContainsNode(SwContentFrame const &rFrame, sal_uLong nNodeIndex)
Definition: txtfrm.cxx:284
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:443
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:501
static bool IsBlanksInString(const SwTextFrame &)
Definition: autofmt.cxx:409
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1293
virtual bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND)=0
Insert string into existing text node at position rRg.Point().
sal_Unicode GetQuote(sal_Unicode cInsChar, bool bSttQuote, LanguageType eLang) const
sal_uLong m_nEndNdIdx
Definition: autofmt.cxx:96
void DeleteSelImpl(SwPaM &rDelPam, SwPaM &rPamToCorrect)
Definition: autofmt.cxx:1180
#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:3403
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1259
FontPitch GetPitch()
void AutoFormat(const SvxSwAutoFormatFlags *pAFlags)
Set our styles according to the respective rules.
Definition: autofmt.cxx:2696
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:954
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:2734
#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:1319
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:2236
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:89
SwContentNode * GetContentNode()
Definition: node.hxx:615
vector_type::size_type size_type
Definition: docary.hxx:228
void SetWidth(long nWidth)
const short lBulletFirstLineOffset
Definition: swtypes.hxx:108
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:223
const SvxAdjustItem & GetAdjust(bool=true) const
Definition: paratr.hxx:180
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:2806
bool FnSetINetAttr(SvxAutoCorrDoc &, const OUString &, sal_Int32 nSttPos, sal_Int32 nEndPos, LanguageType eLang)
const sal_Unicode pBulletChar[6]
Definition: autofmt.cxx:73
short GetTextFirstLineOffset() const
bool SetRedlineText(sal_uInt16 nId)
Definition: autofmt.cxx:207
sal_Unicode cByInputBullet
SwTextFrame * GetFormatted(bool bForceQuickFormat=false)
In case the SwLineLayout was cleared out of the s_pTextCache, recreate it.
Definition: txtfrm.cxx:3354
Marks a node in the document model.
Definition: ndindex.hxx:31
bool IsEndNode() const
Definition: node.hxx:632
virtual bool ReplaceRange(SwPaM &rPam, const OUString &rNewStr, const bool bRegExReplace)=0
Replace selected range in a TextNode with string.
CharClass & GetCharClass(LanguageType eLang) const
Definition: autofmt.cxx:118
sal_uInt16 m_nRedlAutoFormatSeqId
Definition: autofmt.cxx:100
bool HasSwAttrSet() const
Definition: node.hxx:444
ring_container GetRingContainer()
Definition: ring.hxx:240
void SetDistance(sal_uInt16 nNew, SvxBoxItemLine nLine)
static sal_uInt16 GetNumIndent(sal_uInt8 nLvl)
Definition: number.cxx:160
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:1759
SwEditShell * m_pEditShell
Definition: autofmt.cxx:92
const int cnPosEmDash
Definition: autofmt.cxx:74
void BuildHeadLine(sal_uInt16 nLvl)
Definition: autofmt.cxx:1872
SwNodeIndex m_aEndNdIdx
Definition: autofmt.cxx:90
#define STR_AUTOFMTREDL_CPTL_STT_SENT
Definition: comcore.hxx:26
void SetAutoFormatRedlineComment(const OUString *pText, sal_uInt16 nSeqNo=0)
Set comment-text for Redline.
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1223
show all deletes
#define STR_AUTOFMTREDL_SET_TMPL_INDENT
Definition: comcore.hxx:38
const SwPosition * Start() const
Definition: pam.hxx:212
Text body first line indent.
Definition: poolfmt.hxx:252
SwPaM m_aDelPam
Definition: autofmt.cxx:88
static SvxSwAutoFormatFlags * s_pAutoFormatFlags
Definition: editsh.hxx:140
SwTextFrameInfo & SetFrame(const SwTextFrame *pNew)
Definition: frminf.hxx:65
void BuildText()
Definition: autofmt.cxx:1424
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:76
#define STR_AUTOFMTREDL_DETECT_URL
Definition: comcore.hxx:33
#define STR_AUTOFMTREDL_SET_NUMBER_BULLET
Definition: comcore.hxx:42
virtual bool TransliterateRTLWord(sal_Int32 &rSttPos, sal_Int32 nEndPos) override
Definition: acorrect.cxx:500
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
void SetAttrListLevel(int nLevel)
Sets the list level of this text node.
Definition: ndtxt.cxx:4079
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:334
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(105)
SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
Definition: number.cxx:1441
bool IsDefBulletFontUserDefined()
determine if default bullet font is user defined
Definition: number.cxx:1314
static SvxSwAutoFormatFlags * GetAutoFormatFlags()
Definition: autofmt.cxx:2795
static bool HasBreakAttr(const SwTextFrame &)
Definition: autofmt.cxx:1053
SwTextFrame * m_pCurTextFrame
Definition: autofmt.cxx:95
unsigned char sal_uInt8
const std::vector< OUString > & GetAutoFormatNameLst() const
Definition: shellres.hxx:87
#define STR_AUTOFMTREDL_UNDER
Definition: comcore.hxx:30
void Width(long nNew)
Definition: swrect.hxx:187
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:254
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
const sal_uInt16 lNumberIndent
Definition: swtypes.hxx:109
SwNodes & GetNodes()
Definition: doc.hxx:403
const SwPosition * End() const
Definition: pam.hxx:217
static bool IsEmptyLine(const SwTextFrame &rFrame)
Definition: autofmt.cxx:137
virtual bool ChgAutoCorrWord(sal_Int32 &rSttPos, sal_Int32 nEndPos, SvxAutoCorrect &rACorrect, OUString *pPara) override
Definition: acorrect.cxx:365
SvxSwAutoFormatFlags m_aFlags
Definition: autofmt.cxx:87
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:1788
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
static const sal_Unicode * StrChr(const sal_Unicode *pSrc, sal_Unicode c)
Definition: autofmt.cxx:222
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:723
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
static sal_Int32 GetTrailingBlanks(const OUString &rStr)
Definition: autofmt.cxx:720
const SwTextFrame * GetFrame() const
Definition: frminf.hxx:64
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:352
void GetSpaces(std::vector< std::pair< TextFrameIndex, TextFrameIndex >> &, bool bWithLineBreak) const
Definition: frminf.cxx:156
#define DEF_LINE_WIDTH_2
void GotoPrevLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1446
SwTwips GetCharPos(TextFrameIndex nChar, bool bCenter=true) const
Definition: frminf.cxx:109
SwTextNode const * pLastNode
mainly for sanity checks
Definition: txtfrm.hxx:959
static OUString DelLeadingBlanks(const OUString &rStr)
Definition: autofmt.cxx:687
bool m_bMoreLines
Definition: autofmt.cxx:116
#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:2228
bool FnChgWeightUnderl(SvxAutoCorrDoc &, const OUString &, sal_Int32 nEndPos)
bool IsTableNode() const
Definition: node.hxx:640
static bool IsSentenceAtEnd(const SwTextFrame &rTextFrame)
is a dot at the end ??
Definition: autofmt.cxx:1072
Text body hanging indent.
Definition: poolfmt.hxx:253
#define DEF_LINE_WIDTH_0
SwSectionNode * GetSectionNode()
Definition: node.hxx:607
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:475
bool Pop(PopMode)
delete cursor
Definition: crsrsh.cxx:2258
ACFlags GetFlags() const
bool DoUnderline()
Definition: autofmt.cxx:525
void BuildIndent()
Definition: autofmt.cxx:1343
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:854
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:2803
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2069
long GetTextLeft() const
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:205
const int cnPosEnDash
Definition: autofmt.cxx:74
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
const SwTable * InsertTable(const SwInsertTableOptions &rInsTableOpts, const SwPosition &rPos, sal_uInt16 nRows, sal_uInt16 nCols, sal_Int16 eAdjust, const SwTableAutoFormat *pTAFormat=nullptr, const std::vector< sal_uInt16 > *pColArr=nullptr, bool bCalledFromShell=false, bool bNewModel=true)
Insert new table at position.
Definition: ndtbl.cxx:336
SwTextFrame * GetFrame(const SwTextNode &rTextNd) const
get the FORMATTED TextFrame
Definition: autofmt.cxx:229
CharClass & GetAppCharClass()
Definition: init.cxx:708
bool IsTextNode() const
Definition: node.hxx:636
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1238
const sal_uInt16 cnNumBullColls
Definition: autofmt.cxx:83
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
constexpr TypedWhichId< SvxAdjustItem > RES_PARATR_ADJUST(64)
SwRootFrame * getRootFrame()
Definition: frame.hxx:659
SwTextNode * m_pCurTextNd
Definition: autofmt.cxx:94
constexpr TypedWhichId< SvxShadowItem > RES_SHADOW(107)
rtl_TextEncoding GetCharSet() const
sal_uInt16 nPos
SwTextFormatColl & GetNextTextFormatColl() const
Definition: fmtcol.hxx:97
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1315
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:844
static bool IsSpace(const sal_Unicode c)
Definition: autofmt.cxx:128
bool DoTable()
Definition: autofmt.cxx:607
void SetAutoFormatRedline(bool bFlag)
Definition: doc.hxx:1443
#define STR_AUTOFMTREDL_DASH
Definition: comcore.hxx:34
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxItemLine nLine)
Base class of the Writer document model elements.
Definition: node.hxx:79
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:838
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo