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