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