LibreOffice Module sw (master)  1
docnum.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 #include <ftninfo.hxx>
22 #include <ftnidx.hxx>
23 #include <doc.hxx>
24 #include <IDocumentUndoRedo.hxx>
25 #include <IDocumentListsAccess.hxx>
28 #include <IDocumentState.hxx>
30 #include <pam.hxx>
31 #include <ndtxt.hxx>
32 #include <poolfmt.hxx>
33 #include <UndoCore.hxx>
34 #include <UndoRedline.hxx>
35 #include <UndoNumbering.hxx>
36 #include <swundo.hxx>
37 #include <SwUndoFmt.hxx>
38 #include <rolbck.hxx>
39 #include <paratr.hxx>
40 #include <docary.hxx>
41 #include <mvsave.hxx>
42 #include <txtfrm.hxx>
43 #include <rootfrm.hxx>
44 #include <redline.hxx>
45 #include <strings.hrc>
46 #include <SwNodeNum.hxx>
47 #include <list.hxx>
48 #include <calbck.hxx>
49 #include <comphelper/string.hxx>
50 #include <comphelper/random.hxx>
51 #include <o3tl/safeint.hxx>
52 #include <osl/diagnose.h>
53 #include <tools/datetimeutils.hxx>
54 
55 #include <map>
56 #include <stdlib.h>
57 
58 
59 namespace {
60  void lcl_ResetIndentAttrs(SwDoc *pDoc, const SwPaM &rPam, sal_uInt16 marker,
61  SwRootFrame const*const pLayout)
62  {
63  const o3tl::sorted_vector<sal_uInt16> aResetAttrsArray{ marker };
64  // #i114929#
65  // On a selection setup a corresponding Point-and-Mark in order to get
66  // the indentation attribute reset on all paragraphs touched by the selection
67  if ( rPam.HasMark() &&
68  rPam.End()->nNode.GetNode().GetTextNode() )
69  {
70  SwPaM aPam( rPam.Start()->nNode,
71  rPam.End()->nNode );
72  aPam.Start()->nContent = 0;
73  aPam.End()->nContent = rPam.End()->nNode.GetNode().GetTextNode()->Len();
74  pDoc->ResetAttrs( aPam, false, aResetAttrsArray, true, pLayout );
75  }
76  else
77  {
78  pDoc->ResetAttrs( rPam, false, aResetAttrsArray, true, pLayout );
79  }
80  }
81 
82  void ExpandPamForParaPropsNodes(SwPaM& rPam, SwRootFrame const*const pLayout)
83  {
84  if (!pLayout)
85  return;
86 
87  // ensure that selection from the Shell includes the para-props node
88  // to which the attributes should be applied
89  if (rPam.GetPoint()->nNode.GetNode().IsTextNode())
90  {
91  rPam.GetPoint()->nNode = *sw::GetParaPropsNode(*pLayout, rPam.GetPoint()->nNode);
93  }
94  if (rPam.GetMark()->nNode.GetNode().IsTextNode())
95  {
96  rPam.GetMark()->nNode = *sw::GetParaPropsNode(*pLayout, rPam.GetMark()->nNode);
97  rPam.GetMark()->nContent.Assign(rPam.GetMark()->nNode.GetNode().GetContentNode(), 0);
98  }
99  }
100 }
101 
102 static sal_uInt8 GetUpperLvlChg( sal_uInt8 nCurLvl, sal_uInt8 nLevel, sal_uInt16 nMask )
103 {
104  if( 1 < nLevel )
105  {
106  if( nCurLvl + 1 >= nLevel )
107  nCurLvl -= nLevel - 1;
108  else
109  nCurLvl = 0;
110  }
111  return static_cast<sal_uInt8>((nMask - 1) & ~(( 1 << nCurLvl ) - 1));
112 }
113 
115 {
116  if( mpOutlineRule )
117  (*mpOutlineRule) = rRule;
118  else
119  {
120  mpOutlineRule = new SwNumRule( rRule );
121 
122  AddNumRule(mpOutlineRule); // #i36749#
123  }
124 
127 
128  // assure that the outline numbering rule is an automatic rule
129  mpOutlineRule->SetAutoRule( true );
130 
131  // test whether the optional CharFormats are defined in this Document
133 
134  // notify text nodes, which are registered at the outline style, about the
135  // changed outline style
136  SwNumRule::tTextNodeList aTextNodeList;
137  mpOutlineRule->GetTextNodeList( aTextNodeList );
138  for ( SwTextNode* pTextNd : aTextNodeList )
139  {
140  pTextNd->NumRuleChgd();
141 
142  // assure that list level corresponds to outline level
143  if ( pTextNd->GetTextColl()->IsAssignedToListLevelOfOutlineStyle() &&
144  pTextNd->GetAttrListLevel() != pTextNd->GetTextColl()->GetAssignedOutlineStyleLevel() )
145  {
146  pTextNd->SetAttrListLevel( pTextNd->GetTextColl()->GetAssignedOutlineStyleLevel() );
147  }
148  }
149 
152  UpdateNumRule();
153 
154  // update if we have foot notes && numbering by chapter
155  if( !GetFootnoteIdxs().empty() && FTNNUM_CHAPTER == GetFootnoteInfo().m_eNum )
157 
158  getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
159 
161 }
162 
164 {
165  for (auto pColl : *mpTextFormatCollTable)
166  {
167  if(pColl->IsAssignedToListLevelOfOutlineStyle())
168  {
169  // Check only the list style, which is set at the paragraph style
170  const SwNumRuleItem & rCollRuleItem = pColl->GetNumRule( false );
171 
172  if ( rCollRuleItem.GetValue().isEmpty() )
173  {
174  SwNumRule * pMyOutlineRule = GetOutlineNumRule();
175 
176  if (pMyOutlineRule)
177  {
178  SwNumRuleItem aNumItem( pMyOutlineRule->GetName() );
179 
180  pColl->SetFormatAttr(aNumItem);
181  }
182  }
183  }
184  }
185 }
186 
187 // Increase/Decrease
188 bool SwDoc::OutlineUpDown(const SwPaM& rPam, short nOffset,
189  SwRootFrame const*const pLayout)
190 {
191  if( GetNodes().GetOutLineNds().empty() || !nOffset )
192  return false;
193 
194  // calculate the range
195  SwPaM aPam(rPam, nullptr);
196  ExpandPamForParaPropsNodes(aPam, pLayout);
197  const SwOutlineNodes& rOutlNds = GetNodes().GetOutLineNds();
198  const SwNodePtr pSttNd = &aPam.Start()->nNode.GetNode();
199  const SwNodePtr pEndNd = &aPam.End()->nNode.GetNode();
200  SwOutlineNodes::size_type nSttPos, nEndPos;
201 
202  if( !rOutlNds.Seek_Entry( pSttNd, &nSttPos ) &&
203  !nSttPos-- )
204  // we're not in an "Outline section"
205  return false;
206 
207  if( rOutlNds.Seek_Entry( pEndNd, &nEndPos ) )
208  ++nEndPos;
209 
210  // We now have the wanted range in the OutlineNodes array,
211  // so check now if we're not invalidating sublevels
212  // (stepping over the limits)
213 
214  // Here we go:
215  // 1. Create the style array:
216  SwTextFormatColl* aCollArr[ MAXLEVEL ];
217  memset( aCollArr, 0, sizeof( SwTextFormatColl* ) * MAXLEVEL );
218 
219  for( auto pTextFormatColl : *mpTextFormatCollTable )
220  {
221  if (pTextFormatColl->IsAssignedToListLevelOfOutlineStyle())
222  {
223  const int nLevel = pTextFormatColl->GetAssignedOutlineStyleLevel();
224  aCollArr[ nLevel ] = pTextFormatColl;
225  }
226  }
227 
228  int n;
229 
230  /* Find the last occupied level (backward). */
231  for (n = MAXLEVEL - 1; n > 0; n--)
232  {
233  if (aCollArr[n] != nullptr)
234  break;
235  }
236 
237  /* If an occupied level is found, choose next level (which IS
238  unoccupied) until a valid level is found. If no occupied level
239  was found n is 0 and aCollArr[0] is 0. In this case no demoting
240  is possible. */
241  if (aCollArr[n] != nullptr)
242  {
243  while (n < MAXLEVEL - 1)
244  {
245  n++;
246 
247  SwTextFormatColl *aTmpColl =
249 
250  if( aTmpColl->IsAssignedToListLevelOfOutlineStyle() &&
251  aTmpColl->GetAssignedOutlineStyleLevel() == n )
252  {
253  aCollArr[n] = aTmpColl;
254  break;
255  }
256  }
257  }
258 
259  /* Find the first occupied level (forward). */
260  for (n = 0; n < MAXLEVEL - 1; n++)
261  {
262  if (aCollArr[n] != nullptr)
263  break;
264  }
265 
266  /* If an occupied level is found, choose previous level (which IS
267  unoccupied) until a valid level is found. If no occupied level
268  was found n is MAXLEVEL - 1 and aCollArr[MAXLEVEL - 1] is 0. In
269  this case no demoting is possible. */
270  if (aCollArr[n] != nullptr)
271  {
272  while (n > 0)
273  {
274  n--;
275 
276  SwTextFormatColl *aTmpColl =
278 
279  if( aTmpColl->IsAssignedToListLevelOfOutlineStyle() &&
280  aTmpColl->GetAssignedOutlineStyleLevel() == n )
281  {
282  aCollArr[n] = aTmpColl;
283  break;
284  }
285  }
286  }
287 
288  /* --> #i13747#
289 
290  Build a move table that states from which level to which other level
291  an outline will be moved.
292 
293  the move table:
294  aMoveArr[n] = m: replace aCollArr[n] with aCollArr[m]
295  */
296  int aMoveArr[MAXLEVEL];
297  int nStep; // step size for searching in aCollArr: -1 or 1
298  int nNum; // amount of steps for stepping in aCollArr
299 
300  if (nOffset < 0)
301  {
302  nStep = -1;
303  nNum = -nOffset;
304  }
305  else
306  {
307  nStep = 1;
308  nNum = nOffset;
309  }
310 
311  /* traverse aCollArr */
312  for (n = 0; n < MAXLEVEL; n++)
313  {
314  /* If outline level n has an assigned paragraph style step
315  nNum steps forwards (nStep == 1) or backwards (nStep ==
316  -1). One step is to go to the next non-null entry in
317  aCollArr in the selected direction. If nNum steps were
318  possible write the index of the entry found to aCollArr[n],
319  i.e. outline level n will be replaced by outline level
320  aCollArr[n].
321 
322  If outline level n has no assigned paragraph style
323  aMoveArr[n] is set to -1.
324  */
325  if (aCollArr[n] != nullptr)
326  {
327  int m = n;
328  int nCount = nNum;
329 
330  while (nCount > 0 && m + nStep >= 0 && m + nStep < MAXLEVEL)
331  {
332  m += nStep;
333 
334  if (aCollArr[m] != nullptr)
335  nCount--;
336  }
337 
338  if (nCount == 0)
339  aMoveArr[n] = m;
340  else
341  aMoveArr[n] = -1;
342  }
343  else
344  aMoveArr[n] = -1;
345  }
346 
347  /* If moving of the outline levels is applicable, i.e. for all
348  outline levels occurring in the document there has to be a valid
349  target outline level implied by aMoveArr. */
350  bool bMoveApplicable = true;
351  for (auto i = nSttPos; i < nEndPos; ++i)
352  {
353  SwTextNode* pTextNd = rOutlNds[ i ]->GetTextNode();
354  if (pLayout && !sw::IsParaPropsNode(*pLayout, *pTextNd))
355  {
356  continue;
357  }
358  SwTextFormatColl* pColl = pTextNd->GetTextColl();
359 
361  {
362  const int nLevel = pColl->GetAssignedOutlineStyleLevel();
363  if (aMoveArr[nLevel] == -1)
364  bMoveApplicable = false;
365  }
366 
367  // Check on outline level attribute of text node, if text node is
368  // not an outline via a to outline style assigned paragraph style.
369  else
370  {
371  const int nNewOutlineLevel = pTextNd->GetAttrOutlineLevel() + nOffset;
372  if ( nNewOutlineLevel < 1 || nNewOutlineLevel > MAXLEVEL )
373  {
374  bMoveApplicable = false;
375  }
376  }
377  }
378 
379  if (! bMoveApplicable )
380  return false;
381 
382  if (GetIDocumentUndoRedo().DoesUndo())
383  {
386  std::make_unique<SwUndoOutlineLeftRight>(aPam, nOffset) );
387  }
388 
389  // 2. Apply the new style to all Nodes
390  for (auto i = nSttPos; i < nEndPos; ++i)
391  {
392  SwTextNode* pTextNd = rOutlNds[ i ]->GetTextNode();
393  if (pLayout && !sw::IsParaPropsNode(*pLayout, *pTextNd))
394  {
395  continue;
396  }
397  SwTextFormatColl* pColl = pTextNd->GetTextColl();
398 
400  {
401  const int nLevel = pColl->GetAssignedOutlineStyleLevel();
402 
403  OSL_ENSURE(aMoveArr[nLevel] >= 0,
404  "move table: current TextColl not found when building table!");
405 
406  if (nLevel < MAXLEVEL && aMoveArr[nLevel] >= 0)
407  {
408  pColl = aCollArr[ aMoveArr[nLevel] ];
409 
410  if (pColl != nullptr)
411  pTextNd->ChgFormatColl( pColl );
412  }
413 
414  }
415  else if( pTextNd->GetAttrOutlineLevel() > 0)
416  {
417  int nLevel = pTextNd->GetAttrOutlineLevel() + nOffset;
418  if( 0 <= nLevel && nLevel <= MAXLEVEL)
419  pTextNd->SetAttrOutlineLevel( nLevel );
420 
421  }
422  // Undo ???
423  }
424  if (GetIDocumentUndoRedo().DoesUndo())
425  {
427  }
428 
429  ChkCondColls();
431 
432  return true;
433 }
434 
435 // Move up/down
437 {
438  // Do not move to special sections in the nodes array
439  const SwPosition& rStt = *rPam.Start(),
440  & rEnd = &rStt == rPam.GetPoint() ? *rPam.GetMark()
441  : *rPam.GetPoint();
442  if( GetNodes().GetOutLineNds().empty() || !nOffset ||
443  (rStt.nNode.GetIndex() < GetNodes().GetEndOfExtras().GetIndex()) ||
444  (rEnd.nNode.GetIndex() < GetNodes().GetEndOfExtras().GetIndex()))
445  {
446  return false;
447  }
448 
449  SwOutlineNodes::size_type nCurrentPos = 0;
450  SwNodeIndex aSttRg( rStt.nNode ), aEndRg( rEnd.nNode );
451 
452  int nOutLineLevel = MAXLEVEL;
453  SwNode* pSrch = &aSttRg.GetNode();
454 
455  if( pSrch->IsTextNode())
456  nOutLineLevel = static_cast<sal_uInt8>(pSrch->GetTextNode()->GetAttrOutlineLevel()-1);
457  SwNode* pEndSrch = &aEndRg.GetNode();
458  if( !GetNodes().GetOutLineNds().Seek_Entry( pSrch, &nCurrentPos ) )
459  {
460  if( !nCurrentPos )
461  return false; // Promoting or demoting before the first outline => no.
462  if( --nCurrentPos )
463  aSttRg = *GetNodes().GetOutLineNds()[ nCurrentPos ];
464  else if( 0 > nOffset )
465  return false; // Promoting at the top of document?!
466  else
468  }
469  SwOutlineNodes::size_type nTmpPos = 0;
470  // If the given range ends at an outlined text node we have to decide if it has to be a part of
471  // the moving range or not. Normally it will be a sub outline of our chapter
472  // and has to be moved, too. But if the chapter ends with a table(or a section end),
473  // the next text node will be chosen and this could be the next outline of the same level.
474  // The criteria has to be the outline level: sub level => incorporate, same/higher level => no.
475  if( GetNodes().GetOutLineNds().Seek_Entry( pEndSrch, &nTmpPos ) )
476  {
477  if( !pEndSrch->IsTextNode() || pEndSrch == pSrch ||
478  nOutLineLevel < pEndSrch->GetTextNode()->GetAttrOutlineLevel()-1 )
479  ++nTmpPos; // For sub outlines only!
480  }
481 
482  aEndRg = nTmpPos < GetNodes().GetOutLineNds().size()
483  ? *GetNodes().GetOutLineNds()[ nTmpPos ]
485  if( nOffset >= 0 )
486  nCurrentPos = nTmpPos;
487  if( aEndRg == aSttRg )
488  {
489  OSL_FAIL( "Moving outlines: Surprising selection" );
490  ++aEndRg;
491  }
492 
493  const SwNode* pNd;
494  // The following code corrects the range to handle sections (start/end nodes)
495  // The range will be extended if the least node before the range is a start node
496  // which ends inside the range => The complete section will be moved.
497  // The range will be shrunk if the last position is a start node.
498  // The range will be shrunk if the last node is an end node which starts before the range.
499  --aSttRg;
500  while( aSttRg.GetNode().IsStartNode() )
501  {
502  pNd = aSttRg.GetNode().EndOfSectionNode();
503  if( pNd->GetIndex() >= aEndRg.GetIndex() )
504  break;
505  --aSttRg;
506  }
507  ++aSttRg;
508 
509  --aEndRg;
510  while( aEndRg.GetNode().IsStartNode() )
511  --aEndRg;
512 
513  while( aEndRg.GetNode().IsEndNode() )
514  {
515  pNd = aEndRg.GetNode().StartOfSectionNode();
516  if( pNd->GetIndex() >= aSttRg.GetIndex() )
517  break;
518  --aEndRg;
519  }
520  ++aEndRg;
521 
522  // calculation of the new position
523  if( nOffset < 0 && nCurrentPos < o3tl::make_unsigned(-nOffset) )
525  else if( nCurrentPos + nOffset >= GetNodes().GetOutLineNds().size() )
526  pNd = &GetNodes().GetEndOfContent();
527  else
528  pNd = GetNodes().GetOutLineNds()[ nCurrentPos + nOffset ];
529 
530  sal_uLong nNewPos = pNd->GetIndex();
531 
532  // And now a correction of the insert position if necessary...
533  SwNodeIndex aInsertPos( *pNd, -1 );
534  while( aInsertPos.GetNode().IsStartNode() )
535  {
536  // Just before the insert position starts a section:
537  // when I'm moving forward I do not want to enter the section,
538  // when I'm moving backward I want to stay in the section if I'm already a part of,
539  // I want to stay outside if I was outside before.
540  if( nOffset < 0 )
541  {
542  pNd = aInsertPos.GetNode().EndOfSectionNode();
543  if( pNd->GetIndex() >= aEndRg.GetIndex() )
544  break;
545  }
546  --aInsertPos;
547  --nNewPos;
548  }
549 
550  if( nOffset >= 0 )
551  {
552  // When just before the insert position a section ends, it is okay when I'm moving backward
553  // because I want to stay outside the section.
554  // When moving forward I've to check if I started inside or outside the section
555  // because I don't want to enter of leave such a section
556  while( aInsertPos.GetNode().IsEndNode() )
557  {
558  pNd = aInsertPos.GetNode().StartOfSectionNode();
559  if( pNd->GetIndex() >= aSttRg.GetIndex() )
560  break;
561  --aInsertPos;
562  --nNewPos;
563  }
564  }
565  // We do not want to move into tables (at the moment)
566  ++aInsertPos;
567  pNd = &aInsertPos.GetNode();
568  if( pNd->IsTableNode() )
569  pNd = pNd->StartOfSectionNode();
570  if( pNd->FindTableNode() )
571  return false;
572 
573  OSL_ENSURE( aSttRg.GetIndex() > nNewPos || nNewPos >= aEndRg.GetIndex(),
574  "Position lies within Move range" );
575 
576  // If a Position inside the special nodes array sections was calculated,
577  // set it to document start instead.
578  // Sections or Tables at the document start will be pushed backwards.
579  nNewPos = std::max( nNewPos, GetNodes().GetEndOfExtras().GetIndex() + 2 );
580 
581  tools::Long nOffs = nNewPos - ( 0 < nOffset ? aEndRg.GetIndex() : aSttRg.GetIndex());
582  SwPaM aPam( aSttRg, aEndRg, 0, -1 );
583  return MoveParagraph( aPam, nOffs, true );
584 }
585 
587  SwRootFrame const*const pLayout, const OUString& rName, bool const bExact)
588 {
589  SwTextNode * pExactButDeleted(nullptr);
590  SwTextNode* pSavedNode = nullptr;
591  for( auto pOutlNd : rOutlNds )
592  {
593  SwTextNode* pTextNd = pOutlNd->GetTextNode();
594  const OUString sText( pTextNd->GetExpandText(pLayout) );
595  if (sText.startsWith(rName))
596  {
597  if (sText.getLength() == rName.getLength())
598  {
599  if (pLayout && !sw::IsParaPropsNode(*pLayout, *pTextNd))
600  {
601  pExactButDeleted = pTextNd;
602  }
603  else
604  {
605  // Found "exact", set Pos to the Node
606  return pTextNd;
607  }
608  }
609  if (!bExact && !pSavedNode
610  && (!pLayout || sw::IsParaPropsNode(*pLayout, *pTextNd)))
611  {
612  // maybe we just found the text's first part
613  pSavedNode = pTextNd;
614  }
615  }
616  }
617 
618  return bExact ? pExactButDeleted : pSavedNode;
619 }
620 
622  OUString& rName, SwRootFrame const*const pLayout)
623 {
624  // Valid numbers are (always just offsets!):
625  // ([Number]+\.)+ (as a regular expression!)
626  // (Number followed by a period, with 5 repetitions)
627  // i.e.: "1.1.", "1.", "1.1.1."
628  sal_Int32 nPos = 0;
629  OUString sNum = rName.getToken( 0, '.', nPos );
630  if( -1 == nPos )
631  return nullptr; // invalid number!
632 
633  sal_uInt16 nLevelVal[ MAXLEVEL ]; // numbers of all levels
634  memset( nLevelVal, 0, MAXLEVEL * sizeof( nLevelVal[0] ));
635  int nLevel = 0;
636  OUString sName( rName );
637 
638  while( -1 != nPos )
639  {
640  sal_uInt16 nVal = 0;
641  for( sal_Int32 n = 0; n < sNum.getLength(); ++n )
642  {
643  const sal_Unicode c {sNum[ n ]};
644  if( '0' <= c && c <= '9' )
645  {
646  nVal *= 10;
647  nVal += c - '0';
648  }
649  else if( nLevel )
650  break; // "almost" valid number
651  else
652  return nullptr; // invalid number!
653  }
654 
655  if( MAXLEVEL > nLevel )
656  nLevelVal[ nLevel++ ] = nVal;
657 
658  sName = sName.copy( nPos );
659  nPos = 0;
660  sNum = sName.getToken( 0, '.', nPos );
661  // #i4533# without this check all parts delimited by a dot are treated as outline numbers
663  break;
664  }
665  rName = sName; // that's the follow-up text
666 
667  // read all levels, so search the document for this outline
668 
669  // Without OutlineNodes searching doesn't pay off
670  // and we save a crash
671  if( rOutlNds.empty() )
672  return nullptr;
673 
674  // search in the existing outline nodes for the required outline num array
675  for( auto pOutlNd : rOutlNds )
676  {
677  SwTextNode* pNd = pOutlNd->GetTextNode();
678  if ( pNd->GetAttrOutlineLevel() == nLevel )
679  {
680  // #i51089#, #i68289#
681  // Assure, that text node has the correct numbering level. Otherwise,
682  // its number vector will not fit to the searched level.
683  if (pNd->GetNum(pLayout) && pNd->GetActualListLevel() == nLevel - 1)
684  {
685  const SwNodeNum & rNdNum = *(pNd->GetNum(pLayout));
686  SwNumberTree::tNumberVector aLevelVal = rNdNum.GetNumberVector();
687  // now compare with the one searched for
688  bool bEqual = true;
689  nLevel = std::min<int>(nLevel, MAXLEVEL);
690  for( int n = 0; n < nLevel; ++n )
691  {
692  if ( aLevelVal[n] != nLevelVal[n] )
693  {
694  bEqual = false;
695  break;
696  }
697  }
698  if (bEqual)
699  return pNd;
700  }
701  else
702  {
703  // A text node, which has an outline paragraph style applied and
704  // has as hard attribute 'no numbering' set, has an outline level,
705  // but no numbering tree node. Thus, consider this situation in
706  // the assertion condition.
707  OSL_ENSURE( !pNd->GetNumRule(),
708  "<lcl_FindOutlineNum(..)> - text node with outline level and numbering rule, but without numbering tree node. This is a serious defect" );
709  }
710  }
711  }
712 
713  return nullptr;
714 }
715 
716 // rName can contain a Number and/or the Text.
717 // First, we try to find the correct Entry via the Number.
718 // If it exists, we compare the Text to see if it's the right one.
719 // If that's not the case, we search again via the Text. If it is
720 // found, we got the right entry. Or else we use the one found by
721 // searching for the Number.
722 // If we don't have a Number, we search via the Text only.
723 bool SwDoc::GotoOutline(SwPosition& rPos, const OUString& rName, SwRootFrame const*const pLayout) const
724 {
725  if( !rName.isEmpty() )
726  {
727  const SwOutlineNodes& rOutlNds = GetNodes().GetOutLineNds();
728 
729  // 1. step: via the Number:
730  OUString sName( rName );
731  SwTextNode* pNd = ::lcl_FindOutlineNum(rOutlNds, sName, pLayout);
732  if ( pNd )
733  {
734  OUString sExpandedText = pNd->GetExpandText(pLayout);
735  //#i4533# leading numbers followed by a dot have been remove while
736  //searching for the outline position
737  //to compensate this they must be removed from the paragraphs text content, too
738  while(!sExpandedText.isEmpty())
739  {
740  sal_Int32 nPos = 0;
741  OUString sTempNum = sExpandedText.getToken(0, '.', nPos);
742  if( sTempNum.isEmpty() || -1 == nPos ||
744  break;
745  sExpandedText = sExpandedText.copy(nPos);
746  }
747 
748  if( sExpandedText != sName )
749  {
750  SwTextNode *pTmpNd = ::lcl_FindOutlineName(rOutlNds, pLayout, sName, true);
751  if ( pTmpNd ) // found via the Name
752  {
753  if (pLayout && !sw::IsParaPropsNode(*pLayout, *pTmpNd))
754  { // found the correct node but it's deleted!
755  return false; // avoid fallback to inexact search
756  }
757  pNd = pTmpNd;
758  }
759  }
760  rPos.nNode = *pNd;
761  rPos.nContent.Assign( pNd, 0 );
762  return true;
763  }
764 
765  pNd = ::lcl_FindOutlineName(rOutlNds, pLayout, rName, false);
766  if ( pNd )
767  {
768  rPos.nNode = *pNd;
769  rPos.nContent.Assign( pNd, 0 );
770  return true;
771  }
772 
773  // #i68289# additional search on hyperlink URL without its outline numbering part
774  if ( sName != rName )
775  {
776  pNd = ::lcl_FindOutlineName(rOutlNds, pLayout, sName, false);
777  if ( pNd )
778  {
779  rPos.nNode = *pNd;
780  rPos.nContent.Assign( pNd, 0 );
781  return true;
782  }
783  }
784  }
785  return false;
786 }
787 
788 static void lcl_ChgNumRule( SwDoc& rDoc, const SwNumRule& rRule )
789 {
790  SwNumRule* pOld = rDoc.FindNumRulePtr( rRule.GetName() );
791  if (!pOld) //we cannot proceed without the old NumRule
792  return;
793 
794  sal_uInt16 nChgFormatLevel = 0;
795  sal_uInt16 nMask = 1;
796 
797  for ( sal_uInt8 n = 0; n < MAXLEVEL; ++n, nMask <<= 1 )
798  {
799  const SwNumFormat& rOldFormat = pOld->Get( n ), &rNewFormat = rRule.Get( n );
800 
801  if ( rOldFormat != rNewFormat )
802  {
803  nChgFormatLevel |= nMask;
804  }
805  else if ( SVX_NUM_NUMBER_NONE > rNewFormat.GetNumberingType()
806  && 1 < rNewFormat.GetIncludeUpperLevels()
807  && 0 != ( nChgFormatLevel & GetUpperLvlChg( n, rNewFormat.GetIncludeUpperLevels(), nMask ) ) )
808  {
809  nChgFormatLevel |= nMask;
810  }
811  }
812 
813  if( !nChgFormatLevel ) // Nothing has been changed?
814  {
815  const bool bInvalidateNumRule( pOld->IsContinusNum() != rRule.IsContinusNum() );
816  pOld->CheckCharFormats( rDoc );
817  pOld->SetContinusNum( rRule.IsContinusNum() );
818 
819  if ( bInvalidateNumRule )
820  {
821  pOld->SetInvalidRule(true);
822  }
823 
824  return ;
825  }
826 
827  SwNumRule::tTextNodeList aTextNodeList;
828  pOld->GetTextNodeList( aTextNodeList );
829  sal_uInt8 nLvl( 0 );
830  for ( SwTextNode* pTextNd : aTextNodeList )
831  {
832  nLvl = static_cast<sal_uInt8>(pTextNd->GetActualListLevel());
833 
834  if( nLvl < MAXLEVEL )
835  {
836  if( nChgFormatLevel & ( 1 << nLvl ))
837  {
838  pTextNd->NumRuleChgd();
839  }
840  }
841  }
842 
843  for ( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
844  if ( nChgFormatLevel & ( 1 << n ) )
845  pOld->Set( n, rRule.GetNumFormat( n ) );
846 
847  pOld->CheckCharFormats( rDoc );
848  pOld->SetInvalidRule( true );
849  pOld->SetContinusNum( rRule.IsContinusNum() );
850 
851  rDoc.UpdateNumRule();
852 }
853 
854 OUString SwDoc::SetNumRule( const SwPaM& rPam,
855  const SwNumRule& rRule,
856  const bool bCreateNewList,
857  SwRootFrame const*const pLayout,
858  const OUString& sContinuedListId,
859  bool bSetItem,
860  const bool bResetIndentAttrs )
861 {
862  OUString sListId;
863 
864  SwPaM aPam(rPam, nullptr);
865  ExpandPamForParaPropsNodes(aPam, pLayout);
866 
867  SwUndoInsNum * pUndo = nullptr;
868  if (GetIDocumentUndoRedo().DoesUndo())
869  {
870  // Start/End for attributes!
872  pUndo = new SwUndoInsNum( aPam, rRule );
873  GetIDocumentUndoRedo().AppendUndo(std::unique_ptr<SwUndo>(pUndo));
874  }
875 
876  SwNumRule* pNewOrChangedNumRule = FindNumRulePtr( rRule.GetName() );
877  bool bNewNumRuleCreated = false;
878  if ( pNewOrChangedNumRule == nullptr )
879  {
880  // create new numbering rule based on given one
881  pNewOrChangedNumRule = ( *mpNumRuleTable )[MakeNumRule( rRule.GetName(), &rRule )];
882  bNewNumRuleCreated = true;
883  }
884  else if ( rRule != *pNewOrChangedNumRule )
885  {
886  // change existing numbering rule
887  if (pUndo)
888  {
889  pUndo->SaveOldNumRule( *pNewOrChangedNumRule );
890  }
891  ::lcl_ChgNumRule( *this, rRule );
892  if (pUndo)
893  {
894  pUndo->SetLRSpaceEndPos();
895  }
896  }
897 
898  if ( bSetItem )
899  {
900  if ( bCreateNewList )
901  {
902  if ( bNewNumRuleCreated )
903  {
904  // apply list id of list, which has been created for the new list style
905  sListId = pNewOrChangedNumRule->GetDefaultListId();
906  }
907  else
908  {
909  // create new list and apply its list id
910  const SwList* pNewList = getIDocumentListsAccess().createList( OUString(), pNewOrChangedNumRule->GetName() );
911  OSL_ENSURE( pNewList,
912  "<SwDoc::SetNumRule(..)> - could not create new list. Serious defect." );
913  sListId = pNewList->GetListId();
914  }
915  }
916  else if ( !sContinuedListId.isEmpty() )
917  {
918  // apply given list id
919  sListId = sContinuedListId;
920  }
921  if (!sListId.isEmpty())
922  {
925  SetAttrMode::DEFAULT, pLayout);
926  }
927  }
928 
929  if (!aPam.HasMark())
930  {
931  SwTextNode * pTextNd = aPam.GetPoint()->nNode.GetNode().GetTextNode();
932  // robust code: consider case that the PaM doesn't denote a text node - e.g. it denotes a graphic node
933  if ( pTextNd != nullptr )
934  {
935  assert(!pLayout || sw::IsParaPropsNode(*pLayout, *pTextNd));
936  SwNumRule * pRule = pTextNd->GetNumRule();
937 
938  if (pRule && pRule->GetName() == pNewOrChangedNumRule->GetName())
939  {
940  bSetItem = false;
941  if ( !pTextNd->IsInList() )
942  {
943  pTextNd->AddToList();
944  }
945  }
946  // Only clear numbering attribute at text node, if at paragraph
947  // style the new numbering rule is found.
948  else if ( !pRule )
949  {
950  SwTextFormatColl* pColl = pTextNd->GetTextColl();
951  if ( pColl )
952  {
953  SwNumRule* pCollRule = FindNumRulePtr(pColl->GetNumRule().GetValue());
954  if ( pCollRule && pCollRule->GetName() == pNewOrChangedNumRule->GetName() )
955  {
956  pTextNd->ResetAttr( RES_PARATR_NUMRULE );
957  bSetItem = false;
958  }
959  }
960  }
961  }
962  }
963 
964  if ( bSetItem )
965  {
967  SwNumRuleItem(pNewOrChangedNumRule->GetName()),
968  SetAttrMode::DEFAULT, pLayout);
969  }
970 
971  if ( bResetIndentAttrs
972  && pNewOrChangedNumRule->Get( 0 ).GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
973  {
974  ::lcl_ResetIndentAttrs(this, aPam, RES_LR_SPACE, pLayout);
975  }
976 
977  if (GetIDocumentUndoRedo().DoesUndo())
978  {
980  }
981 
983 
984  return sListId;
985 }
986 
987 void SwDoc::SetCounted(const SwPaM & rPam, bool bCounted,
988  SwRootFrame const*const pLayout)
989 {
990  if ( bCounted )
991  {
992  ::lcl_ResetIndentAttrs(this, rPam, RES_PARATR_LIST_ISCOUNTED, pLayout);
993  }
994  else
995  {
998  SetAttrMode::DEFAULT, pLayout);
999  }
1000 }
1001 
1002 void SwDoc::SetNumRuleStart( const SwPosition& rPos, bool bFlag )
1003 {
1004  SwTextNode* pTextNd = rPos.nNode.GetNode().GetTextNode();
1005 
1006  if (!pTextNd)
1007  return;
1008 
1009  const SwNumRule* pRule = pTextNd->GetNumRule();
1010  if( pRule && !bFlag != !pTextNd->IsListRestart())
1011  {
1013  {
1015  std::make_unique<SwUndoNumRuleStart>(rPos, bFlag) );
1016  }
1017 
1018  pTextNd->SetListRestart(bFlag);
1019 
1021  }
1022 }
1023 
1024 void SwDoc::SetNodeNumStart( const SwPosition& rPos, sal_uInt16 nStt )
1025 {
1026  SwTextNode* pTextNd = rPos.nNode.GetNode().GetTextNode();
1027 
1028  if (!pTextNd)
1029  return;
1030 
1031  if ( !pTextNd->HasAttrListRestartValue() ||
1032  pTextNd->GetAttrListRestartValue() != nStt )
1033  {
1035  {
1037  std::make_unique<SwUndoNumRuleStart>(rPos, nStt) );
1038  }
1039  pTextNd->SetAttrListRestartValue( nStt );
1040 
1042  }
1043 }
1044 
1045 // We can only delete if the Rule is unused!
1046 bool SwDoc::DelNumRule( const OUString& rName, bool bBroadcast )
1047 {
1048  sal_uInt16 nPos = FindNumRule( rName );
1049 
1050  if (nPos == USHRT_MAX)
1051  return false;
1052 
1053  if ( (*mpNumRuleTable)[ nPos ] == GetOutlineNumRule() )
1054  {
1055  OSL_FAIL( "<SwDoc::DelNumRule(..)> - No deletion of outline list style. This is serious defect" );
1056  return false;
1057  }
1058 
1059  if( !IsUsed( *(*mpNumRuleTable)[ nPos ] ))
1060  {
1061  if (GetIDocumentUndoRedo().DoesUndo())
1062  {
1064  std::make_unique<SwUndoNumruleDelete>(*(*mpNumRuleTable)[nPos], *this));
1065  }
1066 
1067  if (bBroadcast)
1068  BroadcastStyleOperation(rName, SfxStyleFamily::Pseudo,
1069  SfxHintId::StyleSheetErased);
1070 
1073  // #i34097# DeleteAndDestroy deletes rName if
1074  // rName is directly taken from the numrule.
1075  const OUString aTmpName( rName );
1076  delete (*mpNumRuleTable)[ nPos ];
1077  mpNumRuleTable->erase( mpNumRuleTable->begin() + nPos );
1078  maNumRuleMap.erase(aTmpName);
1079 
1081  return true;
1082  }
1083  return false;
1084 }
1085 
1087 {
1088  SwNumRule* pRule = FindNumRulePtr( rRule.GetName() );
1089  if( !pRule )
1090  return;
1091 
1092  SwUndoInsNum* pUndo = nullptr;
1094  {
1095  pUndo = new SwUndoInsNum( *pRule, rRule, *this );
1096  pUndo->GetHistory();
1097  GetIDocumentUndoRedo().AppendUndo( std::unique_ptr<SwUndo>(pUndo) );
1098  }
1099  ::lcl_ChgNumRule( *this, rRule );
1100  if (pUndo)
1101  {
1102  pUndo->SetLRSpaceEndPos();
1103  }
1104 
1106 }
1107 
1108 bool SwDoc::RenameNumRule(const OUString & rOldName, const OUString & rNewName,
1109  bool bBroadcast)
1110 {
1111  assert(!FindNumRulePtr(rNewName));
1112 
1113  bool bResult = false;
1114  SwNumRule * pNumRule = FindNumRulePtr(rOldName);
1115 
1116  if (pNumRule)
1117  {
1118  if (GetIDocumentUndoRedo().DoesUndo())
1119  {
1121  std::make_unique<SwUndoNumruleRename>(rOldName, rNewName, *this));
1122  }
1123 
1124  SwNumRule::tTextNodeList aTextNodeList;
1125  pNumRule->GetTextNodeList( aTextNodeList );
1126 
1127  pNumRule->SetName( rNewName, getIDocumentListsAccess() );
1128 
1129  SwNumRuleItem aItem(rNewName);
1130 
1131  for ( SwTextNode* pTextNd : aTextNodeList )
1132  {
1133  pTextNd->SetAttr(aItem);
1134  }
1135 
1136  bResult = true;
1137 
1138  if (bBroadcast)
1139  BroadcastStyleOperation(rOldName, SfxStyleFamily::Pseudo,
1140  SfxHintId::StyleSheetModified);
1141  }
1142 
1143  return bResult;
1144 }
1145 
1147 {
1148  for( sal_uInt16 n = GetNumRuleTable().size(); n; )
1149  {
1150  SwNumRule::tTextNodeList aTextNodeList;
1151  GetNumRuleTable()[ --n ]->GetTextNodeList( aTextNodeList );
1152  for ( SwTextNode* pTNd : aTextNodeList )
1153  {
1155  for(SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next() )
1156  if (pFrame->HasAnimation() &&
1157  (!pFrame->GetMergedPara() || pFrame->GetMergedPara()->pParaPropsNode == pTNd))
1158  {
1159  pFrame->StopAnimation( pOut );
1160  }
1161  }
1162  }
1163 }
1164 
1166  const OUString& rOldRule, const OUString& rNewRule )
1167 {
1168  bool bRet = false;
1169  SwNumRule *pOldRule = FindNumRulePtr( rOldRule ),
1170  *pNewRule = FindNumRulePtr( rNewRule );
1171  if( pOldRule && pNewRule && pOldRule != pNewRule )
1172  {
1173  SwUndoInsNum* pUndo = nullptr;
1174  if (GetIDocumentUndoRedo().DoesUndo())
1175  {
1176  // Start/End for attributes!
1178  pUndo = new SwUndoInsNum( rPos, *pNewRule, rOldRule );
1179  GetIDocumentUndoRedo().AppendUndo(std::unique_ptr<SwUndo>(pUndo));
1180  }
1181 
1182  SwNumRule::tTextNodeList aTextNodeList;
1183  pOldRule->GetTextNodeList( aTextNodeList );
1184  if ( !aTextNodeList.empty() )
1185  {
1186  SwRegHistory aRegH( pUndo ? pUndo->GetHistory() : nullptr );
1187  sal_uInt16 nChgFormatLevel = 0;
1188  for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
1189  {
1190  const SwNumFormat& rOldFormat = pOldRule->Get( n ),
1191  & rNewFormat = pNewRule->Get( n );
1192 
1193  if( rOldFormat.GetAbsLSpace() != rNewFormat.GetAbsLSpace() ||
1194  rOldFormat.GetFirstLineOffset() != rNewFormat.GetFirstLineOffset() )
1195  nChgFormatLevel |= ( 1 << n );
1196  }
1197 
1198  const SwTextNode* pGivenTextNode = rPos.nNode.GetNode().GetTextNode();
1199  SwNumRuleItem aRule( rNewRule );
1200  for ( SwTextNode* pTextNd : aTextNodeList )
1201  {
1202  if ( pGivenTextNode &&
1203  pGivenTextNode->GetListId() == pTextNd->GetListId() )
1204  {
1205  aRegH.RegisterInModify( pTextNd, *pTextNd );
1206 
1207  pTextNd->SetAttr( aRule );
1208  pTextNd->NumRuleChgd();
1209  }
1210  }
1213 
1214  bRet = true;
1215  }
1216  }
1217 
1218  return bRet;
1219 }
1220 
1221 namespace
1222 {
1223  struct ListStyleData
1224  {
1225  SwNumRule* pReplaceNumRule;
1226  bool bCreateNewList;
1227  OUString sListId;
1228 
1229  ListStyleData()
1230  : pReplaceNumRule( nullptr ),
1231  bCreateNewList( false ),
1232  sListId()
1233  {}
1234  };
1235 }
1236 
1238 {
1239  OSL_ENSURE( &rPaM.GetDoc() == this, "need same doc" );
1240 
1241  std::map<SwNumRule *, ListStyleData> aMyNumRuleMap;
1242 
1243  bool bFirst = true;
1244 
1245  const sal_uLong nStt = rPaM.Start()->nNode.GetIndex();
1246  const sal_uLong nEnd = rPaM.End()->nNode.GetIndex();
1247  for (sal_uLong n = nStt; n <= nEnd; n++)
1248  {
1249  SwTextNode * pCNd = GetNodes()[n]->GetTextNode();
1250 
1251  if (pCNd)
1252  {
1253  SwNumRule * pRule = pCNd->GetNumRule();
1254 
1255  if (pRule && pRule->IsAutoRule() && ! pRule->IsOutlineRule())
1256  {
1257  ListStyleData aListStyleData = aMyNumRuleMap[pRule];
1258 
1259  if ( aListStyleData.pReplaceNumRule == nullptr )
1260  {
1261  if (bFirst)
1262  {
1263  SwPosition aPos(*pCNd);
1264  aListStyleData.pReplaceNumRule =
1265  const_cast<SwNumRule *>
1266  (SearchNumRule( aPos, false, pCNd->HasNumber(),
1267  false, 0,
1268  aListStyleData.sListId, nullptr, true ));
1269  }
1270 
1271  if ( aListStyleData.pReplaceNumRule == nullptr )
1272  {
1273  aListStyleData.pReplaceNumRule = new SwNumRule(*pRule);
1274  aListStyleData.pReplaceNumRule->SetName( GetUniqueNumRuleName(), getIDocumentListsAccess() );
1275  aListStyleData.bCreateNewList = true;
1276  }
1277 
1278  aMyNumRuleMap[pRule] = aListStyleData;
1279  }
1280 
1281  SwPaM aPam(*pCNd);
1282 
1283  SetNumRule( aPam,
1284  *aListStyleData.pReplaceNumRule,
1285  aListStyleData.bCreateNewList,
1286  nullptr,
1287  aListStyleData.sListId );
1288  if ( aListStyleData.bCreateNewList )
1289  {
1290  aListStyleData.bCreateNewList = false;
1291  aListStyleData.sListId = pCNd->GetListId();
1292  aMyNumRuleMap[pRule] = aListStyleData;
1293  }
1294 
1295  bFirst = false;
1296  }
1297  }
1298  }
1299 }
1300 
1301 bool SwDoc::NoNum( const SwPaM& rPam )
1302 {
1303 
1304  bool bRet = getIDocumentContentOperations().SplitNode( *rPam.GetPoint(), false );
1305  // Do we actually use Numbering at all?
1306  if( bRet )
1307  {
1308  // Set NoNum and Update
1309  const SwNodeIndex& rIdx = rPam.GetPoint()->nNode;
1310  SwTextNode* pNd = rIdx.GetNode().GetTextNode();
1311  const SwNumRule* pRule = pNd->GetNumRule();
1312  if( pRule )
1313  {
1314  pNd->SetCountedInList(false);
1315 
1317  }
1318  else
1319  bRet = false; // no Numbering or just always true?
1320  }
1321  return bRet;
1322 }
1323 
1324 void SwDoc::DelNumRules(const SwPaM& rPam, SwRootFrame const*const pLayout)
1325 {
1326  SwPaM aPam(rPam, nullptr);
1327  ExpandPamForParaPropsNodes(aPam, pLayout);
1328  sal_uLong nStt = aPam.Start()->nNode.GetIndex();
1329  sal_uLong const nEnd = aPam.End()->nNode.GetIndex();
1330 
1331  SwUndoDelNum* pUndo;
1332  if (GetIDocumentUndoRedo().DoesUndo())
1333  {
1334  pUndo = new SwUndoDelNum( aPam );
1335  GetIDocumentUndoRedo().AppendUndo(std::unique_ptr<SwUndo>(pUndo));
1336  }
1337  else
1338  pUndo = nullptr;
1339 
1340  SwRegHistory aRegH( pUndo ? pUndo->GetHistory() : nullptr );
1341 
1342  SwNumRuleItem aEmptyRule;
1343  const SwNode* pOutlNd = nullptr;
1344  for( ; nStt <= nEnd; ++nStt )
1345  {
1346  SwTextNode* pTNd = GetNodes()[ nStt ]->GetTextNode();
1347  if (pLayout && pTNd)
1348  {
1349  pTNd = sw::GetParaPropsNode(*pLayout, *pTNd);
1350  }
1351  SwNumRule* pNumRuleOfTextNode = pTNd ? pTNd->GetNumRule() : nullptr;
1352  if ( pTNd && pNumRuleOfTextNode )
1353  {
1354  // recognize changes of attribute for undo
1355  aRegH.RegisterInModify( pTNd, *pTNd );
1356 
1357  if( pUndo )
1358  pUndo->AddNode( *pTNd );
1359 
1360  // directly set list style attribute is reset, otherwise empty
1361  // list style is applied
1362  const SfxItemSet* pAttrSet = pTNd->GetpSwAttrSet();
1363  if ( pAttrSet &&
1364  pAttrSet->GetItemState( RES_PARATR_NUMRULE, false ) == SfxItemState::SET )
1365  pTNd->ResetAttr( RES_PARATR_NUMRULE );
1366  else
1367  pTNd->SetAttr( aEmptyRule );
1368 
1369  pTNd->ResetAttr( RES_PARATR_LIST_ID );
1374 
1375  if( RES_CONDTXTFMTCOLL == pTNd->GetFormatColl()->Which() )
1376  {
1377  pTNd->ChkCondColl();
1378  }
1379  else if( !pOutlNd &&
1380  static_cast<SwTextFormatColl*>(pTNd->GetFormatColl())->IsAssignedToListLevelOfOutlineStyle() )
1381  {
1382  pOutlNd = pTNd;
1383  }
1384  }
1385  }
1386 
1387  // Finally, update all
1388  UpdateNumRule();
1389 
1390  if( pOutlNd )
1391  GetNodes().UpdateOutlineIdx( *pOutlNd );
1392 }
1393 
1395 {
1396  for (size_t n = 0; n < mpNumRuleTable->size(); ++n)
1397  (*mpNumRuleTable)[n]->SetInvalidRule(true);
1398 }
1399 
1400 // To the next/preceding Bullet at the same Level
1401 static bool lcl_IsNumOk( sal_uInt8 nSrchNum, sal_uInt8& rLower, sal_uInt8& rUpper,
1402  bool bOverUpper, sal_uInt8 nNumber )
1403 {
1404  OSL_ENSURE( nNumber < MAXLEVEL,
1405  "<lcl_IsNumOk(..)> - misusage of method" );
1406 
1407  bool bRet = false;
1408  {
1409  if( bOverUpper ? nSrchNum == nNumber : nSrchNum >= nNumber )
1410  bRet = true;
1411  else if( nNumber > rLower )
1412  rLower = nNumber;
1413  else if( nNumber < rUpper )
1414  rUpper = nNumber;
1415  }
1416  return bRet;
1417 }
1418 
1419 static bool lcl_IsValidPrevNextNumNode( const SwNodeIndex& rIdx )
1420 {
1421  bool bRet = false;
1422  const SwNode& rNd = rIdx.GetNode();
1423  switch( rNd.GetNodeType() )
1424  {
1425  case SwNodeType::End:
1428  break;
1429 
1430  case SwNodeType::Start:
1431  bRet = SwTableBoxStartNode == static_cast<const SwStartNode&>(rNd).GetStartNodeType();
1432  break;
1433 
1434  case SwNodeType::Section: // that one's valid, so proceed
1435  bRet = true;
1436  break;
1437 
1438  default: break;
1439  }
1440  return bRet;
1441 }
1442 
1443 namespace sw {
1444 
1445 void
1446 GotoPrevLayoutTextFrame(SwNodeIndex & rIndex, SwRootFrame const*const pLayout)
1447 {
1448  if (pLayout && pLayout->HasMergedParas())
1449  {
1450  if (rIndex.GetNode().IsTextNode())
1451  {
1453  {
1454  rIndex = *static_cast<SwTextFrame*>(rIndex.GetNode().GetTextNode()->getLayoutFrame(pLayout))->GetMergedPara()->pFirstNode;
1455  }
1456  }
1457  else if (rIndex.GetNode().IsEndNode())
1458  {
1460  {
1461  rIndex = *rIndex.GetNode().StartOfSectionNode();
1462  assert(rIndex.GetNode().IsTableNode());
1463  }
1464  }
1465  }
1466  --rIndex;
1467  if (pLayout && rIndex.GetNode().IsTextNode())
1468  {
1469  rIndex = *sw::GetParaPropsNode(*pLayout, *rIndex.GetNode().GetTextNode());
1470  }
1471 }
1472 
1473 void
1474 GotoNextLayoutTextFrame(SwNodeIndex & rIndex, SwRootFrame const*const pLayout)
1475 {
1476  if (pLayout && pLayout->HasMergedParas())
1477  {
1478  if (rIndex.GetNode().IsTextNode())
1479  {
1481  {
1482  rIndex = *static_cast<SwTextFrame*>(rIndex.GetNode().GetTextNode()->getLayoutFrame(pLayout))->GetMergedPara()->pLastNode;
1483  }
1484  }
1485  else if (rIndex.GetNode().IsTableNode())
1486  {
1488  {
1489  rIndex = *rIndex.GetNode().EndOfSectionNode();
1490  }
1491  }
1492  }
1493  ++rIndex;
1494  if (pLayout && rIndex.GetNode().IsTextNode())
1495  {
1496  rIndex = *sw::GetParaPropsNode(*pLayout, *rIndex.GetNode().GetTextNode());
1497  }
1498 }
1499 
1500 } // namespace sw
1501 
1502 static bool lcl_GotoNextPrevNum( SwPosition& rPos, bool bNext,
1503  bool bOverUpper, sal_uInt8* pUpper, sal_uInt8* pLower,
1504  SwRootFrame const*const pLayout)
1505 {
1506  const SwTextNode* pNd = rPos.nNode.GetNode().GetTextNode();
1507  if (pNd && pLayout)
1508  {
1509  pNd = sw::GetParaPropsNode(*pLayout, *pNd);
1510  }
1511  if( !pNd || nullptr == pNd->GetNumRule() )
1512  return false;
1513 
1514  sal_uInt8 nSrchNum = static_cast<sal_uInt8>(pNd->GetActualListLevel());
1515 
1516  SwNodeIndex aIdx( rPos.nNode );
1517  if( ! pNd->IsCountedInList() )
1518  {
1519  // If NO_NUMLEVEL is switched on, we search the preceding Node with Numbering
1520  bool bError = false;
1521  do {
1522  sw::GotoPrevLayoutTextFrame(aIdx, pLayout);
1523  if( aIdx.GetNode().IsTextNode() )
1524  {
1525  pNd = aIdx.GetNode().GetTextNode();
1526  const SwNumRule* pRule = pNd->GetNumRule();
1527 
1528  if( pRule )
1529  {
1530  sal_uInt8 nTmpNum = static_cast<sal_uInt8>(pNd->GetActualListLevel());
1531  if( pNd->IsCountedInList() || (nTmpNum < nSrchNum ) )
1532  break; // found it!
1533  }
1534  else
1535  bError = true;
1536  }
1537  else
1538  bError = !lcl_IsValidPrevNextNumNode( aIdx );
1539 
1540  } while( !bError );
1541  if( bError )
1542  return false;
1543  }
1544 
1545  sal_uInt8 nLower = nSrchNum, nUpper = nSrchNum;
1546  bool bRet = false;
1547 
1548  const SwTextNode* pLast;
1549  if( bNext )
1550  {
1551  sw::GotoNextLayoutTextFrame(aIdx, pLayout);
1552  pLast = pNd;
1553  }
1554  else
1555  {
1556  sw::GotoPrevLayoutTextFrame(aIdx, pLayout);
1557  pLast = nullptr;
1558  }
1559 
1560  while( bNext ? ( aIdx.GetIndex() < aIdx.GetNodes().Count() - 1 )
1561  : aIdx.GetIndex() != 0 )
1562  {
1563  if( aIdx.GetNode().IsTextNode() )
1564  {
1565  pNd = aIdx.GetNode().GetTextNode();
1566  const SwNumRule* pRule = pNd->GetNumRule();
1567  if( pRule )
1568  {
1569  if( ::lcl_IsNumOk( nSrchNum, nLower, nUpper, bOverUpper,
1570  static_cast<sal_uInt8>(pNd->GetActualListLevel()) ))
1571  {
1572  rPos.nNode = aIdx;
1573  rPos.nContent.Assign( const_cast<SwTextNode*>(pNd), 0 );
1574  bRet = true;
1575  break;
1576  }
1577  else
1578  pLast = pNd;
1579  }
1580  else
1581  break;
1582  }
1583  else if( !lcl_IsValidPrevNextNumNode( aIdx ))
1584  break;
1585 
1586  if( bNext )
1587  sw::GotoNextLayoutTextFrame(aIdx, pLayout);
1588  else
1589  sw::GotoPrevLayoutTextFrame(aIdx, pLayout);
1590  }
1591 
1592  if( !bRet && !bOverUpper && pLast ) // do not iterate over higher numbers, but still to the end
1593  {
1594  if( bNext )
1595  {
1596  rPos.nNode = aIdx;
1597  if( aIdx.GetNode().IsContentNode() )
1598  rPos.nContent.Assign( aIdx.GetNode().GetContentNode(), 0 );
1599  }
1600  else
1601  {
1602  rPos.nNode.Assign( *pLast );
1603  rPos.nContent.Assign( const_cast<SwTextNode*>(pLast), 0 );
1604  }
1605  bRet = true;
1606  }
1607 
1608  if( bRet )
1609  {
1610  if( pUpper )
1611  *pUpper = nUpper;
1612  if( pLower )
1613  *pLower = nLower;
1614  }
1615  return bRet;
1616 }
1617 
1618 bool SwDoc::GotoNextNum(SwPosition& rPos, SwRootFrame const*const pLayout,
1619  bool bOverUpper, sal_uInt8* pUpper, sal_uInt8* pLower)
1620 {
1621  return ::lcl_GotoNextPrevNum(rPos, true, bOverUpper, pUpper, pLower, pLayout);
1622 }
1623 
1625  const bool bForward,
1626  const bool bNum,
1627  const bool bOutline,
1628  int nNonEmptyAllowed,
1629  OUString& sListId,
1630  SwRootFrame const* pLayout,
1631  const bool bInvestigateStartNode)
1632 {
1633  const SwNumRule * pResult = nullptr;
1634  SwTextNode * pTextNd = rPos.nNode.GetNode().GetTextNode();
1635  if (pLayout)
1636  {
1637  pTextNd = sw::GetParaPropsNode(*pLayout, rPos.nNode);
1638  }
1639  SwNode * pStartFromNode = pTextNd;
1640 
1641  if (pTextNd)
1642  {
1643  SwNodeIndex aIdx(rPos.nNode);
1644 
1645  // - the start node has also been investigated, if requested.
1646  const SwNode * pNode = nullptr;
1647  do
1648  {
1649  if ( !bInvestigateStartNode )
1650  {
1651  if (bForward)
1652  sw::GotoNextLayoutTextFrame(aIdx, pLayout);
1653  else
1654  sw::GotoPrevLayoutTextFrame(aIdx, pLayout);
1655  }
1656 
1657  if (aIdx.GetNode().IsTextNode())
1658  {
1659  pTextNd = aIdx.GetNode().GetTextNode();
1660 
1661  const SwNumRule * pNumRule = pTextNd->GetNumRule();
1662  if (pNumRule)
1663  {
1664  if ( ( pNumRule->IsOutlineRule() == bOutline ) &&
1665  ( ( bNum && pNumRule->Get(0).IsEnumeration()) ||
1666  ( !bNum && pNumRule->Get(0).IsItemize() ) ) ) // #i22362#, #i29560#
1667  {
1668  pResult = pTextNd->GetNumRule();
1669  // provide also the list id, to which the text node belongs.
1670  sListId = pTextNd->GetListId();
1671  }
1672 
1673  break;
1674  }
1675  else if (pTextNd->Len() > 0 || nullptr != pTextNd->GetNumRule())
1676  {
1677  if (nNonEmptyAllowed == 0)
1678  break;
1679 
1680  nNonEmptyAllowed--;
1681 
1682  if (nNonEmptyAllowed < 0)
1683  nNonEmptyAllowed = -1;
1684  }
1685  }
1686 
1687  if ( bInvestigateStartNode )
1688  {
1689  if (bForward)
1690  sw::GotoNextLayoutTextFrame(aIdx, pLayout);
1691  else
1692  sw::GotoPrevLayoutTextFrame(aIdx, pLayout);
1693  }
1694 
1695  pNode = &aIdx.GetNode();
1696  }
1697  while (pNode != GetNodes().DocumentSectionStartNode(pStartFromNode) &&
1698  pNode != GetNodes().DocumentSectionEndNode(pStartFromNode));
1699  }
1700 
1701  return pResult;
1702 }
1703 
1704 bool SwDoc::GotoPrevNum(SwPosition& rPos, SwRootFrame const*const pLayout,
1705  bool bOverUpper)
1706 {
1707  return ::lcl_GotoNextPrevNum(rPos, false, bOverUpper, nullptr, nullptr, pLayout);
1708 }
1709 
1710 bool SwDoc::NumUpDown(const SwPaM& rPam, bool bDown, SwRootFrame const*const pLayout)
1711 {
1712  SwPaM aPam(rPam, nullptr);
1713  ExpandPamForParaPropsNodes(aPam, pLayout);
1714  sal_uLong nStt = aPam.Start()->nNode.GetIndex();
1715  sal_uLong const nEnd = aPam.End()->nNode.GetIndex();
1716 
1717  // -> outline nodes are promoted or demoted differently
1718  bool bOnlyOutline = true;
1719  bool bOnlyNonOutline = true;
1720  for (sal_uLong n = nStt; n <= nEnd; n++)
1721  {
1722  SwTextNode * pTextNd = GetNodes()[n]->GetTextNode();
1723 
1724  if (pTextNd)
1725  {
1726  if (pLayout)
1727  {
1728  pTextNd = sw::GetParaPropsNode(*pLayout, *pTextNd);
1729  }
1730  SwNumRule * pRule = pTextNd->GetNumRule();
1731 
1732  if (pRule)
1733  {
1734  if (pRule->IsOutlineRule())
1735  bOnlyNonOutline = false;
1736  else
1737  bOnlyOutline = false;
1738  }
1739  }
1740  }
1741 
1742  bool bRet = true;
1743  sal_Int8 nDiff = bDown ? 1 : -1;
1744 
1745  if (bOnlyOutline)
1746  bRet = OutlineUpDown(rPam, nDiff, pLayout);
1747  else if (bOnlyNonOutline)
1748  {
1749  /* #i24560#
1750  Only promote or demote if all selected paragraphs are
1751  promotable resp. demotable.
1752  */
1753  for (sal_uLong nTmp = nStt; nTmp <= nEnd; ++nTmp)
1754  {
1755  SwTextNode* pTNd = GetNodes()[ nTmp ]->GetTextNode();
1756 
1757  // Make code robust: consider case that the node doesn't denote a
1758  // text node.
1759  if ( pTNd )
1760  {
1761  if (pLayout)
1762  {
1763  pTNd = sw::GetParaPropsNode(*pLayout, *pTNd);
1764  }
1765 
1766  SwNumRule * pRule = pTNd->GetNumRule();
1767 
1768  if (pRule)
1769  {
1770  sal_uInt8 nLevel = static_cast<sal_uInt8>(pTNd->GetActualListLevel());
1771  if( (-1 == nDiff && 0 >= nLevel) ||
1772  (1 == nDiff && MAXLEVEL - 1 <= nLevel))
1773  bRet = false;
1774  }
1775  }
1776  }
1777 
1778  if( bRet )
1779  {
1781  {
1783  std::make_unique<SwUndoNumUpDown>(aPam, nDiff) );
1784  }
1785 
1786  SwTextNode* pPrev = nullptr;
1787  for(sal_uLong nTmp = nStt; nTmp <= nEnd; ++nTmp )
1788  {
1789  SwTextNode* pTNd = GetNodes()[ nTmp ]->GetTextNode();
1790 
1791  if( pTNd)
1792  {
1793  if (pLayout)
1794  {
1795  pTNd = sw::GetParaPropsNode(*pLayout, *pTNd);
1796  if (pTNd == pPrev)
1797  {
1798  continue;
1799  }
1800  pPrev = pTNd;
1801  }
1802 
1803  SwNumRule * pRule = pTNd->GetNumRule();
1804 
1805  if (pRule)
1806  {
1807  sal_uInt8 nLevel = static_cast<sal_uInt8>(pTNd->GetActualListLevel());
1808  nLevel = nLevel + nDiff;
1809 
1810  pTNd->SetAttrListLevel(nLevel);
1811  }
1812  }
1813  }
1814 
1815  ChkCondColls();
1817  }
1818  }
1819 
1820  return bRet;
1821 }
1822 
1823 // this function doesn't contain any numbering-related code, but it is
1824 // primarily called to move numbering-relevant paragraphs around, hence
1825 // it will expand its selection to include full SwTextFrames.
1826 bool SwDoc::MoveParagraph(SwPaM& rPam, tools::Long nOffset, bool const bIsOutlMv)
1827 {
1828  // sw_redlinehide: as long as a layout with Hide mode exists, only
1829  // move nodes that have merged frames *completely*
1830  SwRootFrame const* pLayout(nullptr);
1831  for (SwRootFrame const*const pLay : GetAllLayouts())
1832  {
1833  if (pLay->HasMergedParas())
1834  {
1835  pLayout = pLay;
1836  }
1837  }
1838  if (pLayout)
1839  {
1840  std::pair<SwTextNode *, SwTextNode *> nodes(
1841  sw::GetFirstAndLastNode(*pLayout, rPam.Start()->nNode));
1842  if (nodes.first && nodes.first != &rPam.Start()->nNode.GetNode())
1843  {
1844  assert(nodes.second);
1845  if (nOffset < 0)
1846  {
1847  nOffset += rPam.Start()->nNode.GetIndex() - nodes.first->GetIndex();
1848  if (0 <= nOffset) // hack: there are callers that know what
1849  { // node they want; those should never need
1850  nOffset = -1; // this; other callers just pass in -1
1851  } // and those should still move
1852  }
1853  if (!rPam.HasMark())
1854  {
1855  rPam.SetMark();
1856  }
1857  assert(nodes.first->GetIndex() < rPam.Start()->nNode.GetIndex());
1858  rPam.Start()->nNode = *nodes.first;
1859  rPam.Start()->nContent.Assign(nodes.first, 0);
1860  }
1861  nodes = sw::GetFirstAndLastNode(*pLayout, rPam.End()->nNode);
1862  if (nodes.second && nodes.second != &rPam.End()->nNode.GetNode())
1863  {
1864  assert(nodes.first);
1865  if (0 < nOffset)
1866  {
1867  nOffset -= nodes.second->GetIndex() - rPam.End()->nNode.GetIndex();
1868  if (nOffset <= 0) // hack: there are callers that know what
1869  { // node they want; those should never need
1870  nOffset = +1; // this; other callers just pass in +1
1871  } // and those should still move
1872  }
1873  if (!rPam.HasMark())
1874  {
1875  rPam.SetMark();
1876  }
1877  assert(rPam.End()->nNode.GetIndex() < nodes.second->GetIndex());
1878  rPam.End()->nNode = *nodes.second;
1879  // until end, otherwise Impl will detect overlapping redline
1880  rPam.End()->nContent.Assign(nodes.second, nodes.second->GetTextNode()->Len());
1881  }
1882 
1883  if (nOffset > 0)
1884  { // sw_redlinehide: avoid moving into delete redline, skip forward
1885  if (GetNodes().GetEndOfContent().GetIndex() <= rPam.End()->nNode.GetIndex() + nOffset)
1886  {
1887  return false; // can't move
1888  }
1889  SwNode const* pNode(GetNodes()[rPam.End()->nNode.GetIndex() + nOffset + 1]);
1890  if ( pNode->GetRedlineMergeFlag() != SwNode::Merge::None
1891  && pNode->GetRedlineMergeFlag() != SwNode::Merge::First)
1892  {
1893  for ( ; ; ++nOffset)
1894  {
1895  pNode = GetNodes()[rPam.End()->nNode.GetIndex() + nOffset];
1896  if (pNode->IsTextNode())
1897  {
1898  nodes = GetFirstAndLastNode(*pLayout, *pNode->GetTextNode());
1899  assert(nodes.first && nodes.second);
1900  nOffset += nodes.second->GetIndex() - pNode->GetIndex();
1901  // on last; will be incremented below to behind-last
1902  break;
1903  }
1904  }
1905  }
1906  }
1907  else
1908  { // sw_redlinehide: avoid moving into delete redline, skip backward
1909  if (rPam.Start()->nNode.GetIndex() + nOffset < 1)
1910  {
1911  return false; // can't move
1912  }
1913  SwNode const* pNode(GetNodes()[rPam.Start()->nNode.GetIndex() + nOffset]);
1914  if ( pNode->GetRedlineMergeFlag() != SwNode::Merge::None
1915  && pNode->GetRedlineMergeFlag() != SwNode::Merge::First)
1916  {
1917  for ( ; ; --nOffset)
1918  {
1919  pNode = GetNodes()[rPam.Start()->nNode.GetIndex() + nOffset];
1920  if (pNode->IsTextNode())
1921  {
1922  nodes = GetFirstAndLastNode(*pLayout, *pNode->GetTextNode());
1923  assert(nodes.first && nodes.second);
1924  nOffset -= pNode->GetIndex() - nodes.first->GetIndex();
1925  // on first
1926  break;
1927  }
1928  }
1929  }
1930  }
1931  }
1932  return MoveParagraphImpl(rPam, nOffset, bIsOutlMv, pLayout);
1933 }
1934 
1935 bool SwDoc::MoveParagraphImpl(SwPaM& rPam, tools::Long const nOffset,
1936  bool const bIsOutlMv, SwRootFrame const*const pLayout)
1937 {
1938  const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
1939 
1940  sal_uLong nStIdx = pStt->nNode.GetIndex();
1941  sal_uLong nEndIdx = pEnd->nNode.GetIndex();
1942 
1943  // Here are some sophisticated checks whether the wished PaM will be moved or not.
1944  // For moving outlines (bIsOutlMv) I've already done some checks, so here are two different
1945  // checks...
1946  SwNode *pTmp1;
1947  SwNode *pTmp2;
1948  if( bIsOutlMv )
1949  {
1950  // For moving chapters (outline) the following reason will deny the move:
1951  // if a start node is inside the moved range and its end node outside or vice versa.
1952  // If a start node is the first moved paragraph, its end node has to be within the moved
1953  // range, too (e.g. as last node).
1954  // If an end node is the last node of the moved range, its start node has to be a part of
1955  // the moved section, too.
1956  pTmp1 = GetNodes()[ nStIdx ];
1957  if( pTmp1->IsStartNode() )
1958  { // First is a start node
1959  pTmp2 = pTmp1->EndOfSectionNode();
1960  if( pTmp2->GetIndex() > nEndIdx )
1961  return false; // Its end node is behind the moved range
1962  }
1963  pTmp1 = pTmp1->StartOfSectionNode()->EndOfSectionNode();
1964  if( pTmp1->GetIndex() <= nEndIdx )
1965  return false; // End node inside but start node before moved range => no.
1966  pTmp1 = GetNodes()[ nEndIdx ];
1967  if( pTmp1->IsEndNode() )
1968  { // The last one is an end node
1969  pTmp1 = pTmp1->StartOfSectionNode();
1970  if( pTmp1->GetIndex() < nStIdx )
1971  return false; // Its start node is before the moved range.
1972  }
1973  pTmp1 = pTmp1->StartOfSectionNode();
1974  if( pTmp1->GetIndex() >= nStIdx )
1975  return false; // A start node which ends behind the moved range => no.
1976  }
1977 
1978  sal_uLong nInStIdx, nInEndIdx;
1979  tools::Long nOffs = nOffset;
1980  if( nOffset > 0 )
1981  {
1982  nInEndIdx = nEndIdx;
1983  nEndIdx += nOffset;
1984  ++nOffs;
1985  }
1986  else
1987  {
1988  // Impossible to move to negative index
1989  if( o3tl::make_unsigned(std::abs( nOffset )) > nStIdx)
1990  return false;
1991 
1992  nInEndIdx = nStIdx - 1;
1993  nStIdx += nOffset;
1994  }
1995  nInStIdx = nInEndIdx + 1;
1996  // The following paragraphs shall be swapped:
1997  // Swap [ nStIdx, nInEndIdx ] with [ nInStIdx, nEndIdx ]
1998 
1999  if( nEndIdx >= GetNodes().GetEndOfContent().GetIndex() )
2000  return false;
2001 
2002  if( !bIsOutlMv )
2003  { // And here the restrictions for moving paragraphs other than chapters (outlines)
2004  // The plan is to exchange [nStIdx,nInEndIdx] and [nStartIdx,nEndIdx]
2005  // It will checked if the both "start" nodes as well as the both "end" notes belongs to
2006  // the same start-end-section. This is more restrictive than the conditions checked above.
2007  // E.g. a paragraph will not escape from a section or be inserted to another section.
2008  pTmp1 = GetNodes()[ nStIdx ]->StartOfSectionNode();
2009  pTmp2 = GetNodes()[ nInStIdx ]->StartOfSectionNode();
2010  if( pTmp1 != pTmp2 )
2011  return false; // "start" nodes in different sections
2012  pTmp1 = GetNodes()[ nEndIdx ];
2013  bool bIsEndNode = pTmp1->IsEndNode();
2014  if( !pTmp1->IsStartNode() )
2015  {
2016  pTmp1 = pTmp1->StartOfSectionNode();
2017  if( bIsEndNode ) // For end nodes the first start node is of course inside the range,
2018  pTmp1 = pTmp1->StartOfSectionNode(); // I've to check the start node of the start node.
2019  }
2020  pTmp1 = pTmp1->EndOfSectionNode();
2021  pTmp2 = GetNodes()[ nInEndIdx ];
2022  if( !pTmp2->IsStartNode() )
2023  {
2024  bIsEndNode = pTmp2->IsEndNode();
2025  pTmp2 = pTmp2->StartOfSectionNode();
2026  if( bIsEndNode )
2027  pTmp2 = pTmp2->StartOfSectionNode();
2028  }
2029  pTmp2 = pTmp2->EndOfSectionNode();
2030  if( pTmp1 != pTmp2 )
2031  return false; // The "end" notes are in different sections
2032  }
2033 
2034  // Test for Redlining - Can the Selection be moved at all, actually?
2035  if( !getIDocumentRedlineAccess().IsIgnoreRedline() )
2036  {
2037  SwRedlineTable::size_type nRedlPos = getIDocumentRedlineAccess().GetRedlinePos( pStt->nNode.GetNode(), RedlineType::Delete );
2038  if( SwRedlineTable::npos != nRedlPos )
2039  {
2040  SwPosition aStPos( *pStt ), aEndPos( *pEnd );
2041  aStPos.nContent = 0;
2042  SwContentNode* pCNd = pEnd->nNode.GetNode().GetContentNode();
2043  aEndPos.nContent = pCNd ? pCNd->Len() : 1;
2044  bool bCheckDel = true;
2045 
2046  // There is a some Redline Delete Object for the range
2047  for( ; nRedlPos < getIDocumentRedlineAccess().GetRedlineTable().size(); ++nRedlPos )
2048  {
2049  const SwRangeRedline* pTmp = getIDocumentRedlineAccess().GetRedlineTable()[ nRedlPos ];
2050  if( !bCheckDel || RedlineType::Delete == pTmp->GetType() )
2051  {
2052  const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
2053  switch( ComparePosition( *pRStt, *pREnd, aStPos, aEndPos ))
2054  {
2056  case SwComparePosition::Behind: // Pos1 comes after Pos2
2058  break;
2059 
2061  case SwComparePosition::Before: // Pos1 comes before Pos2
2062  break;
2063  case SwComparePosition::Inside: // Pos1 is completely inside Pos2
2064  // that's valid, but check all following for overlapping
2065  bCheckDel = false;
2066  break;
2067 
2068  case SwComparePosition::Outside: // Pos2 is completely inside Pos1
2069  case SwComparePosition::Equal: // Pos1 is equal to Pos2
2070  case SwComparePosition::OverlapBefore: // Pos1 overlaps Pos2 in the beginning
2071  case SwComparePosition::OverlapBehind: // Pos1 overlaps Pos2 at the end
2072  return false;
2073  }
2074  }
2075  }
2076  }
2077  }
2078 
2079  {
2080  // Send DataChanged before moving. We then can detect
2081  // which objects are still in the range.
2082  // After the move they could come before/after the
2083  // Position.
2084  SwDataChanged aTmp( rPam );
2085  }
2086 
2087  SwNodeIndex aIdx( nOffset > 0 ? pEnd->nNode : pStt->nNode, nOffs );
2088  SwNodeRange aMvRg( pStt->nNode, 0, pEnd->nNode, +1 );
2089 
2090  SwRangeRedline* pOwnRedl = nullptr;
2091  if( getIDocumentRedlineAccess().IsRedlineOn() )
2092  {
2093  // If the range is completely in the own Redline, we can move it!
2094  SwRedlineTable::size_type nRedlPos = getIDocumentRedlineAccess().GetRedlinePos( pStt->nNode.GetNode(), RedlineType::Insert );
2095  if( SwRedlineTable::npos != nRedlPos )
2096  {
2098  const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
2099  SwRangeRedline aTmpRedl( RedlineType::Insert, rPam );
2100  const SwContentNode* pCEndNd = pEnd->nNode.GetNode().GetContentNode();
2101  // Is completely in the range and is the own Redline too?
2102  if( aTmpRedl.IsOwnRedline( *pTmp ) &&
2103  (pRStt->nNode < pStt->nNode ||
2104  (pRStt->nNode == pStt->nNode && !pRStt->nContent.GetIndex()) ) &&
2105  (pEnd->nNode < pREnd->nNode ||
2106  (pEnd->nNode == pREnd->nNode &&
2107  pCEndNd ? pREnd->nContent.GetIndex() == pCEndNd->Len()
2108  : !pREnd->nContent.GetIndex() )) )
2109  {
2110  pOwnRedl = pTmp;
2111  if( nRedlPos + 1 < getIDocumentRedlineAccess().GetRedlineTable().size() )
2112  {
2113  pTmp = getIDocumentRedlineAccess().GetRedlineTable()[ nRedlPos+1 ];
2114  if( *pTmp->Start() == *pREnd )
2115  // then don't!
2116  pOwnRedl = nullptr;
2117  }
2118 
2119  if( pOwnRedl &&
2120  ( pRStt->nNode > aIdx || aIdx > pREnd->nNode ))
2121  {
2122  // it's not in itself, so don't move it
2123  pOwnRedl = nullptr;
2124  }
2125  }
2126  }
2127 
2128  if( !pOwnRedl )
2129  {
2131 
2132  // First the Insert, then the Delete
2133  SwPosition aInsPos( aIdx );
2134  aInsPos.nContent.Assign( aIdx.GetNode().GetContentNode(), 0 );
2135 
2136  SwPaM aPam( pStt->nNode, 0, aMvRg.aEnd, 0 );
2137 
2138  SwPaM& rOrigPam(rPam);
2139  rOrigPam.DeleteMark();
2140  rOrigPam.GetPoint()->nNode = aIdx.GetIndex() - 1;
2141  rOrigPam.GetPoint()->nContent.Assign( rOrigPam.GetContentNode(), 0 );
2142 
2143  bool bDelLastPara = !aInsPos.nNode.GetNode().IsContentNode();
2144  sal_uLong nOrigIdx = aIdx.GetIndex();
2145 
2146  /* When copying to a non-content node Copy will
2147  insert a paragraph before that node and insert before
2148  that inserted node. Copy creates an SwUndoInserts that
2149  does not cover the extra paragraph. Thus we insert the
2150  extra paragraph ourselves, _with_ correct undo
2151  information. */
2152  if (bDelLastPara)
2153  {
2154  /* aInsPos points to the non-content node. Move it to
2155  the previous content node. */
2156  SwPaM aInsPam(aInsPos);
2157  const bool bMoved = aInsPam.Move(fnMoveBackward);
2158  OSL_ENSURE(bMoved, "No content node found!");
2159 
2160  if (bMoved)
2161  {
2162  /* Append the new node after the content node
2163  found. The new position to insert the moved
2164  paragraph at is before the inserted
2165  paragraph. */
2167  aInsPos = *aInsPam.GetPoint();
2168  }
2169  }
2170 
2171  --aIdx; // move before insertion
2172 
2174 
2175  // now delete all the delete redlines that were copied
2176 #ifndef NDEBUG
2177  size_t nRedlines(getIDocumentRedlineAccess().GetRedlineTable().size());
2178 #endif
2179  if (nOffset > 0)
2180  assert(aPam.End()->nNode.GetIndex() - aPam.Start()->nNode.GetIndex() + nOffset == aInsPos.nNode.GetIndex() - aPam.End()->nNode.GetIndex());
2181  else
2182  assert(aPam.Start()->nNode.GetIndex() - aPam.End()->nNode.GetIndex() + nOffset == aInsPos.nNode.GetIndex() - aPam.End()->nNode.GetIndex());
2184  getIDocumentRedlineAccess().GetRedline(*aPam.End(), &i);
2185  for ( ; 0 < i; --i)
2186  { // iterate backwards and offset via the start nodes difference
2187  SwRangeRedline const*const pRedline = getIDocumentRedlineAccess().GetRedlineTable()[i - 1];
2188  if (*pRedline->End() < *aPam.Start())
2189  {
2190  break;
2191  }
2192  if (pRedline->GetType() == RedlineType::Delete)
2193  {
2194  assert(*aPam.Start() <= *pRedline->Start()); // caller's fault
2195  SwRangeRedline* pNewRedline;
2196  {
2197  SwPaM pam(*pRedline, nullptr);
2198  sal_uLong const nCurrentOffset(
2199  nOrigIdx - aPam.Start()->nNode.GetIndex());
2200  pam.GetPoint()->nNode += nCurrentOffset;
2202  pam.GetMark()->nNode += nCurrentOffset;
2204 
2205  pNewRedline = new SwRangeRedline( RedlineType::Delete, pam );
2206  }
2207  // note: effectively this will DeleteAndJoin the pam!
2208  getIDocumentRedlineAccess().AppendRedline(pNewRedline, true);
2209  assert(getIDocumentRedlineAccess().GetRedlineTable().size() <= nRedlines);
2210  }
2211  }
2212 
2213  if( bDelLastPara )
2214  {
2215  // We need to remove the last empty Node again
2216  aIdx = aInsPos.nNode;
2217  SwContentNode* pCNd = SwNodes::GoPrevious( &aInsPos.nNode );
2218  aInsPos.nContent.Assign( pCNd, pCNd ? pCNd->Len() : 0 );
2219 
2220  // All, that are in the to-be-deleted Node, need to be
2221  // moved to the next Node
2223  {
2224  SwPosition* pPos = &pTmp->GetBound();
2225  if( pPos->nNode == aIdx )
2226  {
2227  ++pPos->nNode;
2228  pPos->nContent.Assign( pPos->nNode.GetNode().GetContentNode(),0);
2229  }
2230  pPos = &pTmp->GetBound(false);
2231  if( pPos->nNode == aIdx )
2232  {
2233  ++pPos->nNode;
2234  pPos->nContent.Assign( pPos->nNode.GetNode().GetContentNode(),0);
2235  }
2236  }
2237  CorrRel( aIdx, aInsPos );
2238 
2239  if (pCNd)
2240  pCNd->JoinNext();
2241  }
2242 
2243  ++rOrigPam.GetPoint()->nNode;
2244  rOrigPam.GetPoint()->nContent.Assign( rOrigPam.GetContentNode(), 0 );
2245  assert(*aPam.GetMark() < *aPam.GetPoint());
2246  if (aPam.GetPoint()->nNode.GetNode().IsEndNode())
2247  { // ensure redline ends on content node
2248  --aPam.GetPoint()->nNode;
2249  assert(aPam.GetPoint()->nNode.GetNode().IsTextNode());
2250  SwTextNode *const pNode(aPam.GetPoint()->nNode.GetNode().GetTextNode());
2251  aPam.GetPoint()->nContent.Assign(pNode, pNode->Len());
2252  }
2253 
2255  if (GetIDocumentUndoRedo().DoesUndo())
2256  {
2257  // this should no longer happen in calls from the UI but maybe via API
2258  SAL_WARN_IF((eOld & RedlineFlags::ShowMask) != RedlineFlags::ShowMask,
2259  "sw.core", "redlines will be moved in DeleteAndJoin");
2260 
2264  std::make_unique<SwUndoRedlineDelete>(aPam, SwUndoId::DELETE));
2265  }
2266 
2267  SwRangeRedline* pNewRedline = new SwRangeRedline( RedlineType::Delete, aPam );
2268 
2269  // prevent assertion from aPam's target being deleted
2270  // (Alternatively, one could just let aPam go out of scope, but
2271  // that requires touching a lot of code.)
2272  aPam.GetBound().nContent.Assign( nullptr, 0 );
2273  aPam.GetBound(false).nContent.Assign( nullptr, 0 );
2274 
2275  getIDocumentRedlineAccess().AppendRedline( pNewRedline, true );
2276 
2278  aPam.GetBound(false).nContent.Assign(aPam.GetBound(false).nNode.GetNode().GetContentNode(), 0);
2280 
2284 
2285  return true;
2286  }
2287  }
2288 
2289  if( !pOwnRedl && !getIDocumentRedlineAccess().IsIgnoreRedline() && !getIDocumentRedlineAccess().GetRedlineTable().empty() )
2290  {
2291  SwPaM aTemp(aIdx);
2293  }
2294 
2295  sal_uLong nRedlSttNd(0), nRedlEndNd(0);
2296  if( pOwnRedl )
2297  {
2298  const SwPosition *pRStt = pOwnRedl->Start(), *pREnd = pOwnRedl->End();
2299  nRedlSttNd = pRStt->nNode.GetIndex();
2300  nRedlEndNd = pREnd->nNode.GetIndex();
2301  }
2302 
2303  std::unique_ptr<SwUndoMoveNum> pUndo;
2304  sal_uLong nMoved = 0;
2305  if (GetIDocumentUndoRedo().DoesUndo())
2306  {
2307  pUndo.reset(new SwUndoMoveNum( rPam, nOffset, bIsOutlMv ));
2308  nMoved = rPam.End()->nNode.GetIndex() - rPam.Start()->nNode.GetIndex() + 1;
2309  }
2310 
2311  (void) pLayout; // note: move will insert between aIdx-1 and aIdx
2312  assert(!pLayout // check not moving *into* delete redline (caller's fault)
2316 
2317  if( pUndo )
2318  {
2319  // i57907: Under circumstances (sections at the end of a chapter)
2320  // the rPam.Start() is not moved to the new position.
2321  // But aIdx should be at the new end position and as long as the
2322  // number of moved paragraphs is nMoved, I know, where the new
2323  // position is.
2324  pUndo->SetStartNode( aIdx.GetIndex() - nMoved );
2325  GetIDocumentUndoRedo().AppendUndo(std::move(pUndo));
2326  }
2327 
2328  if( pOwnRedl )
2329  {
2330  SwPosition *pRStt = pOwnRedl->Start(), *pREnd = pOwnRedl->End();
2331  if( pRStt->nNode.GetIndex() != nRedlSttNd )
2332  {
2333  pRStt->nNode = nRedlSttNd;
2334  pRStt->nContent.Assign( pRStt->nNode.GetNode().GetContentNode(),0);
2335  }
2336  if( pREnd->nNode.GetIndex() != nRedlEndNd )
2337  {
2338  pREnd->nNode = nRedlEndNd;
2339  SwContentNode* pCNd = pREnd->nNode.GetNode().GetContentNode();
2340  pREnd->nContent.Assign( pCNd, pCNd ? pCNd->Len() : 0 );
2341  }
2342  }
2343 
2345  return true;
2346 }
2347 
2348 bool SwDoc::NumOrNoNum( const SwNodeIndex& rIdx, bool bDel )
2349 {
2350  bool bResult = false;
2351  SwTextNode * pTextNd = rIdx.GetNode().GetTextNode();
2352 
2353  if (pTextNd && pTextNd->GetNumRule() != nullptr &&
2354  (pTextNd->HasNumber() || pTextNd->HasBullet()))
2355  {
2356  if ( !pTextNd->IsCountedInList() == !bDel)
2357  {
2358  bool bOldNum = bDel;
2359  bool bNewNum = !bDel;
2360  pTextNd->SetCountedInList(bNewNum);
2361 
2363 
2364  bResult = true;
2365 
2366  if (GetIDocumentUndoRedo().DoesUndo())
2367  {
2369  std::make_unique<SwUndoNumOrNoNum>(rIdx, bOldNum, bNewNum));
2370  }
2371  }
2372  else if (bDel && pTextNd->GetNumRule(false) &&
2373  pTextNd->GetActualListLevel() >= 0 &&
2374  pTextNd->GetActualListLevel() < MAXLEVEL)
2375  {
2376  SwPaM aPam(*pTextNd);
2377  DelNumRules(aPam);
2378 
2379  bResult = true;
2380  }
2381  }
2382 
2383  return bResult;
2384 }
2385 
2387  SwRootFrame const*const pLayout)
2388 {
2389  SwNumRule* pRet = nullptr;
2390  SwTextNode* pTNd = rPos.nNode.GetNode().GetTextNode();
2391 
2392  if ( pTNd != nullptr )
2393  {
2394  if (pLayout && !sw::IsParaPropsNode(*pLayout, *pTNd))
2395  {
2396  pTNd = static_cast<SwTextFrame*>(pTNd->getLayoutFrame(pLayout))->GetMergedPara()->pParaPropsNode;
2397  rPos.nNode = *pTNd;
2398  rPos.nContent.Assign(pTNd, 0);
2399  }
2400  pRet = pTNd->GetNumRule();
2401  }
2402 
2403  return pRet;
2404 }
2405 
2406 sal_uInt16 SwDoc::FindNumRule( std::u16string_view rName ) const
2407 {
2408  for( sal_uInt16 n = mpNumRuleTable->size(); n; )
2409  if( (*mpNumRuleTable)[ --n ]->GetName() == rName )
2410  return n;
2411 
2412  return USHRT_MAX;
2413 }
2414 
2415 SwNumRule* SwDoc::FindNumRulePtr( const OUString& rName ) const
2416 {
2417  SwNumRule * pResult = maNumRuleMap[rName];
2418 
2419  if ( !pResult )
2420  {
2421  for (size_t n = 0; n < mpNumRuleTable->size(); ++n)
2422  {
2423  if ((*mpNumRuleTable)[n]->GetName() == rName)
2424  {
2425  pResult = (*mpNumRuleTable)[n];
2426 
2427  break;
2428  }
2429  }
2430  }
2431 
2432  return pResult;
2433 }
2434 
2436 {
2437  if ((SAL_MAX_UINT16 - 1) <= mpNumRuleTable->size())
2438  {
2439  OSL_ENSURE(false, "SwDoc::AddNumRule: table full.");
2440  abort(); // this should never happen on real documents
2441  }
2442  mpNumRuleTable->push_back(pRule);
2443  maNumRuleMap[pRule->GetName()] = pRule;
2444  pRule->SetNumRuleMap(&maNumRuleMap);
2445 
2447 }
2448 
2449 sal_uInt16 SwDoc::MakeNumRule( const OUString &rName,
2450  const SwNumRule* pCpy,
2451  bool bBroadcast,
2452  const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode )
2453 {
2454  SwNumRule* pNew;
2455  if( pCpy )
2456  {
2457  pNew = new SwNumRule( *pCpy );
2458 
2460 
2461  if( pNew->GetName() != rName )
2462  {
2463  pNew->SetPoolFormatId( USHRT_MAX );
2464  pNew->SetPoolHelpId( USHRT_MAX );
2465  pNew->SetPoolHlpFileId( UCHAR_MAX );
2466  pNew->SetDefaultListId( OUString() );
2467  }
2468  pNew->CheckCharFormats( *this );
2469  }
2470  else
2471  {
2472  pNew = new SwNumRule( GetUniqueNumRuleName( &rName ),
2473  eDefaultNumberFormatPositionAndSpaceMode );
2474  }
2475 
2476  sal_uInt16 nRet = mpNumRuleTable->size();
2477 
2478  AddNumRule(pNew);
2479 
2480  if (GetIDocumentUndoRedo().DoesUndo())
2481  {
2483  std::make_unique<SwUndoNumruleCreate>(pNew, *this));
2484  }
2485 
2486  if (bBroadcast)
2487  BroadcastStyleOperation(pNew->GetName(), SfxStyleFamily::Pseudo,
2488  SfxHintId::StyleSheetCreated);
2489 
2490  return nRet;
2491 }
2492 
2493 OUString SwDoc::GetUniqueNumRuleName( const OUString* pChkStr, bool bAutoNum ) const
2494 {
2495  // If we got pChkStr, then the caller expects that in case it's not yet
2496  // used, it'll be returned.
2497  if( IsInMailMerge() && !pChkStr )
2498  {
2499  OUString newName = "MailMergeNumRule"
2500  + OStringToOUString( DateTimeToOString( DateTime( DateTime::SYSTEM )), RTL_TEXTENCODING_ASCII_US )
2501  + OUString::number( mpNumRuleTable->size() + 1 );
2502  return newName;
2503  }
2504 
2505  OUString aName;
2506  if( bAutoNum )
2507  {
2508  static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != nullptr);
2509 
2510  if (bHack)
2511  {
2512  static sal_Int64 nIdCounter = SAL_CONST_INT64(8000000000);
2513  aName = OUString::number(nIdCounter++);
2514  }
2515  else
2516  {
2517  unsigned int const n(comphelper::rng::uniform_uint_distribution(0,
2518  std::numeric_limits<unsigned int>::max()));
2519  aName = OUString::number(n);
2520  }
2521  if( pChkStr && pChkStr->isEmpty() )
2522  pChkStr = nullptr;
2523  }
2524  else if( pChkStr && !pChkStr->isEmpty() )
2525  aName = *pChkStr;
2526  else
2527  {
2528  pChkStr = nullptr;
2529  aName = SwResId( STR_NUMRULE_DEFNAME );
2530  }
2531 
2532  sal_uInt16 nNum(0), nTmp, nFlagSize = ( mpNumRuleTable->size() / 8 ) +2;
2533  std::unique_ptr<sal_uInt8[]> pSetFlags(new sal_uInt8[ nFlagSize ]);
2534  memset( pSetFlags.get(), 0, nFlagSize );
2535 
2536  sal_Int32 nNmLen = aName.getLength();
2537  if( !bAutoNum && pChkStr )
2538  {
2539  while( nNmLen-- && '0' <= aName[nNmLen] && aName[nNmLen] <= '9' )
2540  ; //nop
2541 
2542  if( ++nNmLen < aName.getLength() )
2543  {
2544  aName = aName.copy(0, nNmLen );
2545  pChkStr = nullptr;
2546  }
2547  }
2548 
2549  for( auto const & pNumRule: *mpNumRuleTable )
2550  if( nullptr != pNumRule )
2551  {
2552  const OUString sNm = pNumRule->GetName();
2553  if( sNm.startsWith( aName ) )
2554  {
2555  // Determine Number and set the Flag
2556  nNum = static_cast<sal_uInt16>(sNm.copy( nNmLen ).toInt32());
2557  if( nNum-- && nNum < mpNumRuleTable->size() )
2558  pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
2559  }
2560  if( pChkStr && *pChkStr==sNm )
2561  pChkStr = nullptr;
2562  }
2563 
2564  if( !pChkStr )
2565  {
2566  // All Numbers have been flagged accordingly, so identify the right Number
2567  nNum = mpNumRuleTable->size();
2568  for( sal_uInt16 n = 0; n < nFlagSize; ++n )
2569  {
2570  nTmp = pSetFlags[ n ];
2571  if( 0xff != nTmp )
2572  {
2573  // identify the Number
2574  nNum = n * 8;
2575  while( nTmp & 1 )
2576  {
2577  ++nNum;
2578  nTmp >>= 1;
2579  }
2580  break;
2581  }
2582  }
2583  }
2584  if( pChkStr && !pChkStr->isEmpty() )
2585  return *pChkStr;
2586  return aName + OUString::number( ++nNum );
2587 }
2588 
2590 {
2591  const SwNumRuleTable& rNmTable = GetNumRuleTable();
2592  for( size_t n = 0; n < rNmTable.size(); ++n )
2593  if( rNmTable[ n ]->IsInvalidRule() )
2594  rNmTable[ n ]->Validate();
2595 }
2596 
2597 void SwDoc::MarkListLevel( const OUString& sListId,
2598  const int nListLevel,
2599  const bool bValue )
2600 {
2601  SwList* pList = getIDocumentListsAccess().getListByName( sListId );
2602 
2603  if ( pList )
2604  {
2605  // Set new marked list level and notify all affected nodes of the changed mark.
2606  pList->MarkListLevel( nListLevel, bValue );
2607  }
2608 }
2609 
2611  SwRootFrame const& rLayout)
2612 {
2613  bool bResult = false;
2614 
2615  const SwTextNode *const pTextNode = sw::GetParaPropsNode(rLayout, rPos.nNode);
2616  if ( pTextNode != nullptr )
2617  {
2618  bResult = pTextNode->IsFirstOfNumRule(rLayout);
2619  }
2620 
2621  return bResult;
2622 }
2623 
2624 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:686
Starts a section of nodes in the document model.
Definition: node.hxx:312
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:157
virtual sal_Int32 Len() const
Definition: node.cxx:1245
SwHistory * GetHistory()
void DeleteMark()
Definition: pam.hxx:177
void SetListRestart(bool bRestart)
Definition: ndtxt.cxx:4113
bool IsInMailMerge() const
Definition: doc.hxx:961
sal_uLong GetIndex() const
Definition: node.hxx:291
bool IsUsed(const sw::BroadcastingModify &) const
Definition: poolfmt.cxx:86
int GetAssignedOutlineStyleLevel() const
Definition: fmtcol.cxx:599
sal_uLong Count() const
Definition: ndarr.hxx:142
bool HasBullet() const
Returns if this text node has a bullet.
Definition: ndtxt.cxx:3103
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
void SaveOldNumRule(const SwNumRule &rOld)
Definition: unnum.cxx:149
Marks a position in the document model.
Definition: pam.hxx:35
void UpdateFramesForAddDeleteRedline(SwDoc &rDoc, SwPaM const &rPam)
void ChkCondColls()
Definition: doc.cxx:1791
bool IsSectionNode() const
Definition: node.hxx:648
const SwNodeNum * GetNum(SwRootFrame const *pLayout=nullptr) const
Definition: ndtxt.cxx:3957
SwComparePosition ComparePosition(const T &rStt1, const T &rEnd1, const T &rStt2, const T &rEnd2)
Definition: pam.hxx:77
virtual void deleteListsByDefaultListStyle(const OUString &rListStyleName)=0
void SetAutoRule(bool bFlag)
Definition: numrule.hxx:231
virtual bool SetAttr(const SfxPoolItem &) override
overriding to handle change of certain paragraph attributes
Definition: ndtxt.cxx:4898
virtual void createListForListStyle(const OUString &rListStyleName)=0
virtual AppendResult AppendRedline(SwRangeRedline *pNewRedl, bool bCallDelete)=0
Append a new redline.
signed char sal_Int8
const SwNumFormat * GetNumFormat(sal_uInt16 i) const
Definition: number.cxx:89
const OUString & GetListId() const
Definition: list.cxx:246
SwNodeIndex nNode
Definition: pam.hxx:37
static bool lcl_IsValidPrevNextNumNode(const SwNodeIndex &rIdx)
Definition: docnum.cxx:1419
void AddToList()
Definition: ndtxt.cxx:4275
bool isdigitAsciiString(std::string_view rString)
std::vector< SwNode * >::difference_type difference_type
void SetPoolHlpFileId(sal_uInt8 nId)
Definition: numrule.hxx:258
SVX_NUM_NUMBER_NONE
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:276
virtual void SetModified()=0
Must be called manually at changes of format.
sal_uIntPtr sal_uLong
virtual SwList * createList(const OUString &rListId, const OUString &rDefaultListStyleName)=0
long Long
constexpr TypedWhichId< SwNumRuleItem > RES_PARATR_NUMRULE(72)
Pos1 is as large as Pos2.
const SwPosition * GetMark() const
Definition: pam.hxx:209
const OUString & GetDefaultListId() const
Definition: numrule.hxx:195
constexpr TypedWhichId< SfxInt16Item > RES_PARATR_LIST_RESTARTVALUE(85)
Definition: list.hxx:35
bool IsAutoRule() const
Definition: numrule.hxx:230
bool NumOrNoNum(const SwNodeIndex &rIdx, bool bDel=false)
Definition: docnum.cxx:2348
Pos1 completely contained in Pos2.
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1212
bool MoveOutlinePara(const SwPaM &rPam, SwOutlineNodes::difference_type nOffset)
Outline - move up / move down.
Definition: docnum.cxx:436
sal_Int64 n
virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Closes undo block.
OUString GetListId() const
Definition: ndtxt.cxx:4382
Definition: doc.hxx:187
TElementType * Next()
Definition: calbck.hxx:333
void SetContinusNum(bool bFlag)
Definition: numrule.hxx:237
SwSectionNode is derived from SwStartNode.
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1310
static SwTextNode * lcl_FindOutlineName(const SwOutlineNodes &rOutlNds, SwRootFrame const *const pLayout, const OUString &rName, bool const bExact)
Definition: docnum.cxx:586
SwNode & GetNode() const
Definition: ndindex.hxx:119
void SetNumRuleStart(const SwPosition &rPos, bool bFlag=true)
Definition: docnum.cxx:1002
OUString newName(std::u16string_view aNewPrefix, const OUString &aOldPrefix, std::u16string_view old_Name)
const OUString & GetName() const
Definition: numrule.hxx:225
OUString GetUniqueNumRuleName(const OUString *pChkStr=nullptr, bool bAutoNum=true) const
Definition: docnum.cxx:2493
SwNumberTree::tNumberVector GetNumberVector() const
Returns level numbers of this node.
constexpr TypedWhichId< SwConditionTextFormatColl > RES_CONDTXTFMTCOLL(160)
SwPosition & GetBound(bool bOne=true)
Definition: pam.hxx:245
Dialog to specify the properties of date form field.
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:144
bool NumUpDown(const SwPaM &, bool bDown, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:1710
std::unordered_map< OUString, SwNumRule * > maNumRuleMap
Definition: doc.hxx:272
void UpdateOutlineIdx(const SwNode &)
Update all OutlineNodes starting from Node.
Definition: ndnum.cxx:75
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
bool HasNumber() const
Returns if this text node has a number.
Definition: ndtxt.cxx:3086
bool IsListRestart() const
Definition: ndtxt.cxx:4129
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4106
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4022
constexpr TypedWhichId< SfxBoolItem > RES_PARATR_LIST_ISRESTART(84)
unsigned int uniform_uint_distribution(unsigned int a, unsigned int b)
show all inserts
size_type size() const
Definition: docary.hxx:266
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
virtual void UpdateExpFields(SwTextField *pField, bool bUpdateRefFields)=0
Pos1 end touches at Pos2 start.
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:357
bool IsOwnRedline(const SwRangeRedline &rRedl) const
Definition: redline.hxx:240
sal_uInt16 sal_Unicode
bool IsAssignedToListLevelOfOutlineStyle() const
Definition: fmtcol.hxx:114
SwNodeType GetNodeType() const
Definition: node.hxx:145
SwIndex nContent
Definition: pam.hxx:38
constexpr TypedWhichId< SfxInt16Item > RES_PARATR_LIST_LEVEL(83)
#define SAL_MAX_UINT16
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
static SwNumRule * GetNumRuleAtPos(SwPosition &rPos, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:2386
void ResetAttrs(const SwPaM &rRg, bool bTextAttr=true, const o3tl::sorted_vector< sal_uInt16 > &rAttrs=o3tl::sorted_vector< sal_uInt16 >(), const bool bSendDataChangedEvents=true, SwRootFrame const *pLayout=nullptr)
Reset attributes.
Definition: docfmt.cxx:242
bool NoNum(const SwPaM &)
Definition: docnum.cxx:1301
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:426
check if target position is in fly anchored at source range
std::unique_ptr< SwNumRuleTable > mpNumRuleTable
Definition: doc.hxx:269
int nCount
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
static sal_uInt8 GetUpperLvlChg(sal_uInt8 nCurLvl, sal_uInt8 nLevel, sal_uInt16 nMask)
Definition: docnum.cxx:102
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
void PropagateOutlineRule()
Definition: docnum.cxx:163
bool IsStartNode() const
Definition: node.hxx:628
Pos2 completely contained in Pos1.
void MarkListLevel(const int nListLevel, const bool bValue)
Definition: list.cxx:282
o3tl::sorted_vector< SwRootFrame * > GetAllLayouts()
Definition: doclay.cxx:1671
void SetCountedInList(bool bCounted)
Definition: ndtxt.cxx:4229
void GotoNextLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1474
Pos1 before Pos2.
void ChkCondColl(const SwTextFormatColl *pColl=nullptr)
Definition: node.cxx:1976
SwHistory * GetHistory()
Definition: unnum.cxx:142
RedlineFlags on.
bool RenameNumRule(const OUString &aOldName, const OUString &aNewName, bool bBroadcast=false)
Definition: docnum.cxx:1108
void SetNumRuleMap(std::unordered_map< OUString, SwNumRule * > *pNumRuleMap)
Register this rule in a "name->numrule" map.
Definition: number.cxx:155
size_type size() const
virtual bool DoesUndo() const =0
Is Undo enabled?
void SetPoolFormatId(sal_uInt16 nId)
Definition: numrule.hxx:252
const char * sName
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:163
bool IsContinusNum() const
Definition: numrule.hxx:236
static SwTextNode * lcl_FindOutlineNum(const SwOutlineNodes &rOutlNds, OUString &rName, SwRootFrame const *const pLayout)
Definition: docnum.cxx:621
void SetCounted(const SwPaM &, bool bCounted, SwRootFrame const *pLayout)
Definition: docnum.cxx:987
void DelNumRules(const SwPaM &, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:1324
void SetNodeNumStart(const SwPosition &rPos, sal_uInt16 nStt)
Definition: docnum.cxx:1024
bool IsContentNode() const
Definition: node.hxx:632
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:452
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:504
virtual SwRedlineTable::size_type GetRedlinePos(const SwNode &rNode, RedlineType nType) const =0
sal_uInt16 FindNumRule(std::u16string_view rName) const
Definition: docnum.cxx:2406
std::unique_ptr< SwTextFormatColls > mpTextFormatCollTable
Definition: doc.hxx:244
SwNumRule * FindNumRulePtr(const OUString &rName) const
Definition: docnum.cxx:2415
virtual SwList * getListByName(const OUString &rListId) const =0
virtual void AppendUndo(std::unique_ptr< SwUndo > pUndo)=0
Add new Undo action.
void AddNumRule(SwNumRule *pRule)
Add numbering rule to document.
Definition: docnum.cxx:2435
virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Opens undo block.
void MakeUniqueNumRules(const SwPaM &rPaM)
Definition: docnum.cxx:1237
void CheckCharFormats(SwDoc &rDoc)
Tests whether the CharFormats are from the given doc and copies them if appropriate.
Definition: number.cxx:517
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
int i
static bool lcl_IsNumOk(sal_uInt8 nSrchNum, sal_uInt8 &rLower, sal_uInt8 &rUpper, bool bOverUpper, sal_uInt8 nNumber)
Definition: docnum.cxx:1401
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:132
sal_Int32 GetAbsLSpace() const
const SwPosition * GetPoint() const
Definition: pam.hxx:207
virtual bool CopyRange(SwPaM &rPam, SwPosition &rPos, SwCopyFlags flags) const =0
Copy a selected content range to a position.
Pos1 start touches at Pos2 end.
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
void SetAttrOutlineLevel(int nLevel)
Sets the out line level at a text node.
Definition: ndtxt.cxx:4027
TElementType * First()
Definition: calbck.hxx:325
SwContentNode * GetContentNode()
Definition: node.hxx:619
vector_type::size_type size_type
Definition: docary.hxx:228
const OUString & GetValue() const
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
void UpdateNumRule()
Definition: docnum.cxx:2589
bool IsEnumeration() const
Definition: number.cxx:229
static bool lcl_GotoNextPrevNum(SwPosition &rPos, bool bNext, bool bOverUpper, sal_uInt8 *pUpper, sal_uInt8 *pLower, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1502
size_t size() const
Definition: docary.hxx:84
virtual SwFormatColl * ChgFormatColl(SwFormatColl *) override
Definition: ndtxt.cxx:3921
static OUString GetOutlineRuleName()
Definition: number.cxx:74
void SetRuleType(SwNumRuleType eNew)
Definition: numrule.hxx:213
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2813
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:394
virtual void deleteListForListStyle(const OUString &rListStyleName)=0
bool MoveParagraph(SwPaM &, tools::Long nOffset, bool bIsOutlMv=false)
Move selected paragraphs (not only numberings) according to offsets.
Definition: docnum.cxx:1826
bool IsItemize() const
Definition: number.cxx:237
size
SwNumRule * mpOutlineRule
Definition: doc.hxx:253
void SetPoolHelpId(sal_uInt16 nId)
Definition: numrule.hxx:256
Marks a node in the document model.
Definition: ndindex.hxx:31
bool IsEndNode() const
Definition: node.hxx:636
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:231
void GetTextNodeList(SwNumRule::tTextNodeList &rTextNodeList) const
Definition: number.cxx:123
OUString SwResId(const char *pId)
Definition: swmodule.cxx:166
SwStartNodeType GetStartNodeType() const
Definition: node.hxx:329
bool empty() const
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
virtual bool MoveNodeRange(SwNodeRange &, SwNodeIndex &, SwMoveFlags)=0
show all deletes
const SwPosition * Start() const
Definition: pam.hxx:212
const SwNumRuleItem & GetNumRule(bool=true) const
Definition: paratr.hxx:233
void SetOutlineNumRule(const SwNumRule &rRule)
Definition: docnum.cxx:114
bool ReplaceNumRule(const SwPosition &rPos, const OUString &rOldRule, const OUString &rNewRule)
Definition: docnum.cxx:1165
SwTextNode * GetParaPropsNode(SwRootFrame const &rLayout, SwNodeIndex const &rNode)
Definition: txtfrm.cxx:324
virtual const SwRangeRedline * GetRedline(const SwPosition &rPos, SwRedlineTable::size_type *pFndPos) const =0
std::vector< tSwNumTreeNumber > tNumberVector
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
void CorrRel(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset=0, bool bMoveCursor=false)
Definition: doccorr.cxx:305
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:79
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
virtual bool SplitRedline(const SwPaM &rPam)=0
void SetAttrListLevel(int nLevel)
Sets the list level of this text node.
Definition: ndtxt.cxx:4076
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
void Set(sal_uInt16 i, const SwNumFormat *)
Definition: number.cxx:608
void SetInvalidRule(bool bFlag)
Definition: number.cxx:927
OUString GetExpandText(SwRootFrame const *pLayout, const sal_Int32 nIdx=0, const sal_Int32 nLen=-1, const bool bWithNum=false, const bool bAddSpaceAfterListLabelStr=false, const bool bWithSpacesForLevel=false, const ExpandMode eAdditionalMode=ExpandMode::ExpandFootnote) const
add 4th optional parameter indicating, when that a spa...
Definition: ndtxt.cxx:3374
bool GotoOutline(SwPosition &rPos, const OUString &rName, SwRootFrame const *=nullptr) const
Definition: docnum.cxx:723
void StopNumRuleAnimations(const OutputDevice *)
Definition: docnum.cxx:1146
#define SAL_WARN_IF(condition, area, stream)
static void lcl_ChgNumRule(SwDoc &rDoc, const SwNumRule &rRule)
Definition: docnum.cxx:788
SwNumberTree::tSwNumTreeNumber GetAttrListRestartValue() const
Definition: ndtxt.cxx:4183
void SetDefaultListId(const OUString &sDefaultListId)
Definition: numrule.hxx:191
Pos1 overlaps Pos2 at the end.
unsigned char sal_uInt8
const SwNodes & GetNodes() const
Definition: ndindex.hxx:156
void MarkListLevel(const OUString &sListId, const int nListLevel, const bool bValue)
Marks/Unmarks a list level of a certain list.
Definition: docnum.cxx:2597
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:254
virtual bool InsertPoolItem(const SwPaM &rRg, const SfxPoolItem &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr, bool bExpandCharToPara=false, SwTextAttr **ppNewTextAttr=nullptr)=0
Insert an attribute.
const SwNumRuleTable & GetNumRuleTable() const
Definition: doc.hxx:1067
virtual void SetRedlineFlags(RedlineFlags eMode)=0
Set a new redline mode.
OUString aName
sal_Int32 GetIndex() const
Definition: index.hxx:91
OString DateTimeToOString(const DateTime &rDateTime)
bool IsCountedInList() const
Definition: ndtxt.cxx:4244
constexpr TypedWhichId< SfxBoolItem > RES_PARATR_LIST_ISCOUNTED(86)
SwNodes & GetNodes()
Definition: doc.hxx:408
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
const SwPosition * End() const
Definition: pam.hxx:217
SwNodeIndex aEnd
Definition: ndindex.hxx:133
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1810
static bool GotoNextNum(SwPosition &, SwRootFrame const *pLayout, bool bOverUpper=true, sal_uInt8 *pUpper=nullptr, sal_uInt8 *pLower=nullptr)
Definition: docnum.cxx:1618
sal_uInt16 MakeNumRule(const OUString &rName, const SwNumRule *pCpy=nullptr, bool bBroadcast=false, const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode=SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
Definition: docnum.cxx:2449
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
bool IsFirstOfNumRule(SwRootFrame const &rLayout) const
Definition: ndtxt.cxx:4353
bool IsParaPropsNode(SwRootFrame const &rLayout, SwTextNode const &rNode)
Definition: txtfrm.cxx:307
virtual SwContentNode * JoinNext()
Definition: node.cxx:1524
sal_Int32 GetFirstLineOffset() const
static bool IsFirstOfNumRuleAtPos(const SwPosition &rPos, SwRootFrame const &rLayout)
Definition: docnum.cxx:2610
static bool GotoPrevNum(SwPosition &, SwRootFrame const *pLayout, bool bOverUpper=true)
Definition: docnum.cxx:1704
std::vector< SwTextNode * > tTextNodeList
Definition: numrule.hxx:97
virtual bool AppendTextNode(SwPosition &rPos)=0
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:357
void GotoPrevLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1446
virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart)=0
Split a node at rPos (implemented only for TextNode).
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:633
virtual RedlineFlags GetRedlineFlags() const =0
Query the currently set redline mode.
bool IsTableNode() const
Definition: node.hxx:644
SwFormatColl * GetFormatColl() const
Definition: node.hxx:456
bool IsInList() const
Definition: ndtxt.cxx:4348
SwDoc & GetDoc() const
Definition: pam.hxx:243
bool HasMergedParas() const
Definition: rootfrm.hxx:424
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:478
Pos1 behind Pos2.
bool DelNumRule(const OUString &rName, bool bBroadCast=false)
Definition: docnum.cxx:1046
bool MoveParagraphImpl(SwPaM &, tools::Long nOffset, bool bIsOutlMv, SwRootFrame const *)
Definition: docnum.cxx:1935
bool Seek_Entry(SwNode *rP, size_type *pnPos) const
Definition: ndnum.cxx:32
tuple m
void InvalidateNumRules()
Definition: docnum.cxx:1394
void SetName(const OUString &rNm, IDocumentListsAccess &rDocListAccess)
Definition: number.cxx:103
virtual const SwRedlineTable & GetRedlineTable() const =0
virtual bool ResetAttr(sal_uInt16 nWhich1, sal_uInt16 nWhich2=0) override
Definition: ndtxt.cxx:5128
std::vector< SwNode * >::size_type size_type
const SwNumRule * SearchNumRule(const SwPosition &rPos, const bool bForward, const bool bNum, const bool bOutline, int nNonEmptyAllowed, OUString &sListId, SwRootFrame const *pLayout, const bool bInvestigateStartNode=false)
Searches for a text node with a numbering rule.
Definition: docnum.cxx:1624
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
void UpdateAllFootnote()
Definition: ftnidx.cxx:267
void AddNode(const SwTextNode &rNd)
Definition: unnum.cxx:197
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:161
bool HasAttrListRestartValue() const
Definition: ndtxt.cxx:4178
IDocumentListsAccess const & getIDocumentListsAccess() const
Definition: doc.cxx:293
bool IsTextNode() const
Definition: node.hxx:640
static constexpr size_type npos
Definition: docary.hxx:229
Merge GetRedlineMergeFlag() const
Definition: node.hxx:98
bool OutlineUpDown(const SwPaM &rPam, short nOffset, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:188
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:629
void SetAttrListRestartValue(SwNumberTree::tSwNumTreeNumber nNum)
Definition: ndtxt.cxx:4157
Pos1 overlaps Pos2 at the beginning.
bool IsOutlineRule() const
Definition: numrule.hxx:242
void BroadcastStyleOperation(const OUString &rName, SfxStyleFamily eFamily, SfxHintId nOp)
Definition: docdesc.cxx:636
constexpr TypedWhichId< SfxStringItem > RES_PARATR_LIST_ID(RES_PARATR_LIST_BEGIN)
void SetLRSpaceEndPos()
Definition: unnum.cxx:119
sal_uInt16 nPos
std::pair< SwTextNode *, SwTextNode * > GetFirstAndLastNode(SwRootFrame const &rLayout, SwNodeIndex const &rPos)
Definition: txtfrm.cxx:351
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:845
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1025
void ChgNumRuleFormats(const SwNumRule &rRule)
Definition: docnum.cxx:1086
SwNodeIndex & Assign(SwNodes const &rNds, sal_uLong)
Definition: ndindex.hxx:272
Base class of the Writer document model elements.
Definition: node.hxx:80
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:839
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo