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 <editeng/lrspitem.hxx>
22 #include <ftninfo.hxx>
23 #include <ftnidx.hxx>
24 #include <doc.hxx>
25 #include <IDocumentUndoRedo.hxx>
26 #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 <tools/datetimeutils.hxx>
53 
54 #include <map>
55 #include <stdlib.h>
56 
57 
58 namespace {
59  void lcl_ResetIndentAttrs(SwDoc *pDoc, const SwPaM &rPam, sal_uInt16 marker,
60  SwRootFrame const*const pLayout)
61  {
62  std::set<sal_uInt16> aResetAttrsArray;
63  aResetAttrsArray.insert( 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  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->IsHideRedlines())
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->IsHideRedlines())
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  sal_uInt8 nTmpNum;
1529 
1530  if( pRule )
1531  {
1532  nTmpNum = static_cast<sal_uInt8>(pNd->GetActualListLevel());
1533  if( pNd->IsCountedInList() || (nTmpNum < nSrchNum ) )
1534  break; // found it!
1535  }
1536  else
1537  bError = true;
1538  }
1539  else
1540  bError = !lcl_IsValidPrevNextNumNode( aIdx );
1541 
1542  } while( !bError );
1543  if( bError )
1544  return false;
1545  }
1546 
1547  sal_uInt8 nLower = nSrchNum, nUpper = nSrchNum;
1548  bool bRet = false;
1549 
1550  const SwTextNode* pLast;
1551  if( bNext )
1552  {
1553  sw::GotoNextLayoutTextFrame(aIdx, pLayout);
1554  pLast = pNd;
1555  }
1556  else
1557  {
1558  sw::GotoPrevLayoutTextFrame(aIdx, pLayout);
1559  pLast = nullptr;
1560  }
1561 
1562  while( bNext ? ( aIdx.GetIndex() < aIdx.GetNodes().Count() - 1 )
1563  : aIdx.GetIndex() != 0 )
1564  {
1565  if( aIdx.GetNode().IsTextNode() )
1566  {
1567  pNd = aIdx.GetNode().GetTextNode();
1568  const SwNumRule* pRule = pNd->GetNumRule();
1569  if( pRule )
1570  {
1571  if( ::lcl_IsNumOk( nSrchNum, nLower, nUpper, bOverUpper,
1572  static_cast<sal_uInt8>(pNd->GetActualListLevel()) ))
1573  {
1574  rPos.nNode = aIdx;
1575  rPos.nContent.Assign( const_cast<SwTextNode*>(pNd), 0 );
1576  bRet = true;
1577  break;
1578  }
1579  else
1580  pLast = pNd;
1581  }
1582  else
1583  break;
1584  }
1585  else if( !lcl_IsValidPrevNextNumNode( aIdx ))
1586  break;
1587 
1588  if( bNext )
1589  sw::GotoNextLayoutTextFrame(aIdx, pLayout);
1590  else
1591  sw::GotoPrevLayoutTextFrame(aIdx, pLayout);
1592  }
1593 
1594  if( !bRet && !bOverUpper && pLast ) // do not iterate over higher numbers, but still to the end
1595  {
1596  if( bNext )
1597  {
1598  rPos.nNode = aIdx;
1599  if( aIdx.GetNode().IsContentNode() )
1600  rPos.nContent.Assign( aIdx.GetNode().GetContentNode(), 0 );
1601  }
1602  else
1603  {
1604  rPos.nNode.Assign( *pLast );
1605  rPos.nContent.Assign( const_cast<SwTextNode*>(pLast), 0 );
1606  }
1607  bRet = true;
1608  }
1609 
1610  if( bRet )
1611  {
1612  if( pUpper )
1613  *pUpper = nUpper;
1614  if( pLower )
1615  *pLower = nLower;
1616  }
1617  return bRet;
1618 }
1619 
1620 bool SwDoc::GotoNextNum(SwPosition& rPos, SwRootFrame const*const pLayout,
1621  bool bOverUpper, sal_uInt8* pUpper, sal_uInt8* pLower)
1622 {
1623  return ::lcl_GotoNextPrevNum(rPos, true, bOverUpper, pUpper, pLower, pLayout);
1624 }
1625 
1627  const bool bForward,
1628  const bool bNum,
1629  const bool bOutline,
1630  int nNonEmptyAllowed,
1631  OUString& sListId,
1632  SwRootFrame const* pLayout,
1633  const bool bInvestigateStartNode)
1634 {
1635  const SwNumRule * pResult = nullptr;
1636  SwTextNode * pTextNd = rPos.nNode.GetNode().GetTextNode();
1637  if (pLayout)
1638  {
1639  pTextNd = sw::GetParaPropsNode(*pLayout, rPos.nNode);
1640  }
1641  SwNode * pStartFromNode = pTextNd;
1642 
1643  if (pTextNd)
1644  {
1645  SwNodeIndex aIdx(rPos.nNode);
1646 
1647  // - the start node has also been investigated, if requested.
1648  const SwNode * pNode = nullptr;
1649  do
1650  {
1651  if ( !bInvestigateStartNode )
1652  {
1653  if (bForward)
1654  sw::GotoNextLayoutTextFrame(aIdx, pLayout);
1655  else
1656  sw::GotoPrevLayoutTextFrame(aIdx, pLayout);
1657  }
1658 
1659  if (aIdx.GetNode().IsTextNode())
1660  {
1661  pTextNd = aIdx.GetNode().GetTextNode();
1662 
1663  const SwNumRule * pNumRule = pTextNd->GetNumRule();
1664  if (pNumRule)
1665  {
1666  if ( ( pNumRule->IsOutlineRule() == bOutline ) &&
1667  ( ( bNum && pNumRule->Get(0).IsEnumeration()) ||
1668  ( !bNum && pNumRule->Get(0).IsItemize() ) ) ) // #i22362#, #i29560#
1669  {
1670  pResult = pTextNd->GetNumRule();
1671  // provide also the list id, to which the text node belongs.
1672  sListId = pTextNd->GetListId();
1673  }
1674 
1675  break;
1676  }
1677  else if (pTextNd->Len() > 0 || nullptr != pTextNd->GetNumRule())
1678  {
1679  if (nNonEmptyAllowed == 0)
1680  break;
1681 
1682  nNonEmptyAllowed--;
1683 
1684  if (nNonEmptyAllowed < 0)
1685  nNonEmptyAllowed = -1;
1686  }
1687  }
1688 
1689  if ( bInvestigateStartNode )
1690  {
1691  if (bForward)
1692  sw::GotoNextLayoutTextFrame(aIdx, pLayout);
1693  else
1694  sw::GotoPrevLayoutTextFrame(aIdx, pLayout);
1695  }
1696 
1697  pNode = &aIdx.GetNode();
1698  }
1699  while (pNode != GetNodes().DocumentSectionStartNode(pStartFromNode) &&
1700  pNode != GetNodes().DocumentSectionEndNode(pStartFromNode));
1701  }
1702 
1703  return pResult;
1704 }
1705 
1706 bool SwDoc::GotoPrevNum(SwPosition& rPos, SwRootFrame const*const pLayout,
1707  bool bOverUpper)
1708 {
1709  return ::lcl_GotoNextPrevNum(rPos, false, bOverUpper, nullptr, nullptr, pLayout);
1710 }
1711 
1712 bool SwDoc::NumUpDown(const SwPaM& rPam, bool bDown, SwRootFrame const*const pLayout)
1713 {
1714  SwPaM aPam(rPam, nullptr);
1715  ExpandPamForParaPropsNodes(aPam, pLayout);
1716  sal_uLong nStt = aPam.Start()->nNode.GetIndex();
1717  sal_uLong const nEnd = aPam.End()->nNode.GetIndex();
1718 
1719  // -> outline nodes are promoted or demoted differently
1720  bool bOnlyOutline = true;
1721  bool bOnlyNonOutline = true;
1722  for (sal_uLong n = nStt; n <= nEnd; n++)
1723  {
1724  SwTextNode * pTextNd = GetNodes()[n]->GetTextNode();
1725 
1726  if (pTextNd)
1727  {
1728  if (pLayout)
1729  {
1730  pTextNd = sw::GetParaPropsNode(*pLayout, *pTextNd);
1731  }
1732  SwNumRule * pRule = pTextNd->GetNumRule();
1733 
1734  if (pRule)
1735  {
1736  if (pRule->IsOutlineRule())
1737  bOnlyNonOutline = false;
1738  else
1739  bOnlyOutline = false;
1740  }
1741  }
1742  }
1743 
1744  bool bRet = true;
1745  sal_Int8 nDiff = bDown ? 1 : -1;
1746 
1747  if (bOnlyOutline)
1748  bRet = OutlineUpDown(rPam, nDiff, pLayout);
1749  else if (bOnlyNonOutline)
1750  {
1751  /* #i24560#
1752  Only promote or demote if all selected paragraphs are
1753  promotable resp. demotable.
1754  */
1755  for (sal_uLong nTmp = nStt; nTmp <= nEnd; ++nTmp)
1756  {
1757  SwTextNode* pTNd = GetNodes()[ nTmp ]->GetTextNode();
1758 
1759  // Make code robust: consider case that the node doesn't denote a
1760  // text node.
1761  if ( pTNd )
1762  {
1763  if (pLayout)
1764  {
1765  pTNd = sw::GetParaPropsNode(*pLayout, *pTNd);
1766  }
1767 
1768  SwNumRule * pRule = pTNd->GetNumRule();
1769 
1770  if (pRule)
1771  {
1772  sal_uInt8 nLevel = static_cast<sal_uInt8>(pTNd->GetActualListLevel());
1773  if( (-1 == nDiff && 0 >= nLevel) ||
1774  (1 == nDiff && MAXLEVEL - 1 <= nLevel))
1775  bRet = false;
1776  }
1777  }
1778  }
1779 
1780  if( bRet )
1781  {
1783  {
1785  std::make_unique<SwUndoNumUpDown>(aPam, nDiff) );
1786  }
1787 
1788  SwTextNode* pPrev = nullptr;
1789  for(sal_uLong nTmp = nStt; nTmp <= nEnd; ++nTmp )
1790  {
1791  SwTextNode* pTNd = GetNodes()[ nTmp ]->GetTextNode();
1792 
1793  if( pTNd)
1794  {
1795  if (pLayout)
1796  {
1797  pTNd = sw::GetParaPropsNode(*pLayout, *pTNd);
1798  if (pTNd == pPrev)
1799  {
1800  continue;
1801  }
1802  pPrev = pTNd;
1803  }
1804 
1805  SwNumRule * pRule = pTNd->GetNumRule();
1806 
1807  if (pRule)
1808  {
1809  sal_uInt8 nLevel = static_cast<sal_uInt8>(pTNd->GetActualListLevel());
1810  nLevel = nLevel + nDiff;
1811 
1812  pTNd->SetAttrListLevel(nLevel);
1813  }
1814  }
1815  }
1816 
1817  ChkCondColls();
1819  }
1820  }
1821 
1822  return bRet;
1823 }
1824 
1825 // this function doesn't contain any numbering-related code, but it is
1826 // primarily called to move numbering-relevant paragraphs around, hence
1827 // it will expand its selection to include full SwTextFrames.
1828 bool SwDoc::MoveParagraph(SwPaM& rPam, long nOffset, bool const bIsOutlMv)
1829 {
1830  // sw_redlinehide: as long as a layout with Hide mode exists, only
1831  // move nodes that have merged frames *completely*
1832  SwRootFrame const* pLayout(nullptr);
1833  for (SwRootFrame const*const pLay : GetAllLayouts())
1834  {
1835  if (pLay->IsHideRedlines())
1836  {
1837  pLayout = pLay;
1838  }
1839  }
1840  if (pLayout)
1841  {
1842  std::pair<SwTextNode *, SwTextNode *> nodes(
1843  sw::GetFirstAndLastNode(*pLayout, rPam.Start()->nNode));
1844  if (nodes.first && nodes.first != &rPam.Start()->nNode.GetNode())
1845  {
1846  assert(nodes.second);
1847  if (nOffset < 0)
1848  {
1849  nOffset += rPam.Start()->nNode.GetIndex() - nodes.first->GetIndex();
1850  if (0 <= nOffset) // hack: there are callers that know what
1851  { // node they want; those should never need
1852  nOffset = -1; // this; other callers just pass in -1
1853  } // and those should still move
1854  }
1855  if (!rPam.HasMark())
1856  {
1857  rPam.SetMark();
1858  }
1859  assert(nodes.first->GetIndex() < rPam.Start()->nNode.GetIndex());
1860  rPam.Start()->nNode = *nodes.first;
1861  rPam.Start()->nContent.Assign(nodes.first, 0);
1862  }
1863  nodes = sw::GetFirstAndLastNode(*pLayout, rPam.End()->nNode);
1864  if (nodes.second && nodes.second != &rPam.End()->nNode.GetNode())
1865  {
1866  assert(nodes.first);
1867  if (0 < nOffset)
1868  {
1869  nOffset -= nodes.second->GetIndex() - rPam.End()->nNode.GetIndex();
1870  if (nOffset <= 0) // hack: there are callers that know what
1871  { // node they want; those should never need
1872  nOffset = +1; // this; other callers just pass in +1
1873  } // and those should still move
1874  }
1875  if (!rPam.HasMark())
1876  {
1877  rPam.SetMark();
1878  }
1879  assert(rPam.End()->nNode.GetIndex() < nodes.second->GetIndex());
1880  rPam.End()->nNode = *nodes.second;
1881  // until end, otherwise Impl will detect overlapping redline
1882  rPam.End()->nContent.Assign(nodes.second, nodes.second->GetTextNode()->Len());
1883  }
1884 
1885  if (nOffset > 0)
1886  { // sw_redlinehide: avoid moving into delete redline, skip forward
1887  if (GetNodes().GetEndOfContent().GetIndex() <= rPam.End()->nNode.GetIndex() + nOffset)
1888  {
1889  return false; // can't move
1890  }
1891  SwNode const* pNode(GetNodes()[rPam.End()->nNode.GetIndex() + nOffset + 1]);
1892  if ( pNode->GetRedlineMergeFlag() != SwNode::Merge::None
1893  && pNode->GetRedlineMergeFlag() != SwNode::Merge::First)
1894  {
1895  for ( ; ; ++nOffset)
1896  {
1897  pNode = GetNodes()[rPam.End()->nNode.GetIndex() + nOffset];
1898  if (pNode->IsTextNode())
1899  {
1900  nodes = GetFirstAndLastNode(*pLayout, *pNode->GetTextNode());
1901  assert(nodes.first && nodes.second);
1902  nOffset += nodes.second->GetIndex() - pNode->GetIndex();
1903  // on last; will be incremented below to behind-last
1904  break;
1905  }
1906  }
1907  }
1908  }
1909  else
1910  { // sw_redlinehide: avoid moving into delete redline, skip backward
1911  if (rPam.Start()->nNode.GetIndex() + nOffset < 1)
1912  {
1913  return false; // can't move
1914  }
1915  SwNode const* pNode(GetNodes()[rPam.Start()->nNode.GetIndex() + nOffset]);
1916  if ( pNode->GetRedlineMergeFlag() != SwNode::Merge::None
1917  && pNode->GetRedlineMergeFlag() != SwNode::Merge::First)
1918  {
1919  for ( ; ; --nOffset)
1920  {
1921  pNode = GetNodes()[rPam.Start()->nNode.GetIndex() + nOffset];
1922  if (pNode->IsTextNode())
1923  {
1924  nodes = GetFirstAndLastNode(*pLayout, *pNode->GetTextNode());
1925  assert(nodes.first && nodes.second);
1926  nOffset -= pNode->GetIndex() - nodes.first->GetIndex();
1927  // on first
1928  break;
1929  }
1930  }
1931  }
1932  }
1933  }
1934  return MoveParagraphImpl(rPam, nOffset, bIsOutlMv, pLayout);
1935 }
1936 
1937 bool SwDoc::MoveParagraphImpl(SwPaM& rPam, long const nOffset,
1938  bool const bIsOutlMv, SwRootFrame const*const pLayout)
1939 {
1940  const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
1941 
1942  sal_uLong nStIdx = pStt->nNode.GetIndex();
1943  sal_uLong nEndIdx = pEnd->nNode.GetIndex();
1944 
1945  // Here are some sophisticated checks whether the wished PaM will be moved or not.
1946  // For moving outlines (bIsOutlMv) I've already done some checks, so here are two different
1947  // checks...
1948  SwNode *pTmp1;
1949  SwNode *pTmp2;
1950  if( bIsOutlMv )
1951  {
1952  // For moving chapters (outline) the following reason will deny the move:
1953  // if a start node is inside the moved range and its end node outside or vice versa.
1954  // If a start node is the first moved paragraph, its end node has to be within the moved
1955  // range, too (e.g. as last node).
1956  // If an end node is the last node of the moved range, its start node has to be a part of
1957  // the moved section, too.
1958  pTmp1 = GetNodes()[ nStIdx ];
1959  if( pTmp1->IsStartNode() )
1960  { // First is a start node
1961  pTmp2 = pTmp1->EndOfSectionNode();
1962  if( pTmp2->GetIndex() > nEndIdx )
1963  return false; // Its end node is behind the moved range
1964  }
1965  pTmp1 = pTmp1->StartOfSectionNode()->EndOfSectionNode();
1966  if( pTmp1->GetIndex() <= nEndIdx )
1967  return false; // End node inside but start node before moved range => no.
1968  pTmp1 = GetNodes()[ nEndIdx ];
1969  if( pTmp1->IsEndNode() )
1970  { // The last one is an end node
1971  pTmp1 = pTmp1->StartOfSectionNode();
1972  if( pTmp1->GetIndex() < nStIdx )
1973  return false; // Its start node is before the moved range.
1974  }
1975  pTmp1 = pTmp1->StartOfSectionNode();
1976  if( pTmp1->GetIndex() >= nStIdx )
1977  return false; // A start node which ends behind the moved range => no.
1978  }
1979 
1980  sal_uLong nInStIdx, nInEndIdx;
1981  long nOffs = nOffset;
1982  if( nOffset > 0 )
1983  {
1984  nInEndIdx = nEndIdx;
1985  nEndIdx += nOffset;
1986  ++nOffs;
1987  }
1988  else
1989  {
1990  // Impossible to move to negative index
1991  if( o3tl::make_unsigned(std::abs( nOffset )) > nStIdx)
1992  return false;
1993 
1994  nInEndIdx = nStIdx - 1;
1995  nStIdx += nOffset;
1996  }
1997  nInStIdx = nInEndIdx + 1;
1998  // The following paragraphs shall be swapped:
1999  // Swap [ nStIdx, nInEndIdx ] with [ nInStIdx, nEndIdx ]
2000 
2001  if( nEndIdx >= GetNodes().GetEndOfContent().GetIndex() )
2002  return false;
2003 
2004  if( !bIsOutlMv )
2005  { // And here the restrictions for moving paragraphs other than chapters (outlines)
2006  // The plan is to exchange [nStIdx,nInEndIdx] and [nStartIdx,nEndIdx]
2007  // It will checked if the both "start" nodes as well as the both "end" notes belongs to
2008  // the same start-end-section. This is more restrictive than the conditions checked above.
2009  // E.g. a paragraph will not escape from a section or be inserted to another section.
2010  pTmp1 = GetNodes()[ nStIdx ]->StartOfSectionNode();
2011  pTmp2 = GetNodes()[ nInStIdx ]->StartOfSectionNode();
2012  if( pTmp1 != pTmp2 )
2013  return false; // "start" nodes in different sections
2014  pTmp1 = GetNodes()[ nEndIdx ];
2015  bool bIsEndNode = pTmp1->IsEndNode();
2016  if( !pTmp1->IsStartNode() )
2017  {
2018  pTmp1 = pTmp1->StartOfSectionNode();
2019  if( bIsEndNode ) // For end nodes the first start node is of course inside the range,
2020  pTmp1 = pTmp1->StartOfSectionNode(); // I've to check the start node of the start node.
2021  }
2022  pTmp1 = pTmp1->EndOfSectionNode();
2023  pTmp2 = GetNodes()[ nInEndIdx ];
2024  if( !pTmp2->IsStartNode() )
2025  {
2026  bIsEndNode = pTmp2->IsEndNode();
2027  pTmp2 = pTmp2->StartOfSectionNode();
2028  if( bIsEndNode )
2029  pTmp2 = pTmp2->StartOfSectionNode();
2030  }
2031  pTmp2 = pTmp2->EndOfSectionNode();
2032  if( pTmp1 != pTmp2 )
2033  return false; // The "end" notes are in different sections
2034  }
2035 
2036  // Test for Redlining - Can the Selection be moved at all, actually?
2037  if( !getIDocumentRedlineAccess().IsIgnoreRedline() )
2038  {
2039  SwRedlineTable::size_type nRedlPos = getIDocumentRedlineAccess().GetRedlinePos( pStt->nNode.GetNode(), RedlineType::Delete );
2040  if( SwRedlineTable::npos != nRedlPos )
2041  {
2042  SwPosition aStPos( *pStt ), aEndPos( *pEnd );
2043  aStPos.nContent = 0;
2044  SwContentNode* pCNd = pEnd->nNode.GetNode().GetContentNode();
2045  aEndPos.nContent = pCNd ? pCNd->Len() : 1;
2046  bool bCheckDel = true;
2047 
2048  // There is a some Redline Delete Object for the range
2049  for( ; nRedlPos < getIDocumentRedlineAccess().GetRedlineTable().size(); ++nRedlPos )
2050  {
2051  const SwRangeRedline* pTmp = getIDocumentRedlineAccess().GetRedlineTable()[ nRedlPos ];
2052  if( !bCheckDel || RedlineType::Delete == pTmp->GetType() )
2053  {
2054  const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
2055  switch( ComparePosition( *pRStt, *pREnd, aStPos, aEndPos ))
2056  {
2058  case SwComparePosition::Behind: // Pos1 comes after Pos2
2060  break;
2061 
2063  case SwComparePosition::Before: // Pos1 comes before Pos2
2064  break;
2065  case SwComparePosition::Inside: // Pos1 is completely inside Pos2
2066  // that's valid, but check all following for overlapping
2067  bCheckDel = false;
2068  break;
2069 
2070  case SwComparePosition::Outside: // Pos2 is completely inside Pos1
2071  case SwComparePosition::Equal: // Pos1 is equal to Pos2
2072  case SwComparePosition::OverlapBefore: // Pos1 overlaps Pos2 in the beginning
2073  case SwComparePosition::OverlapBehind: // Pos1 overlaps Pos2 at the end
2074  return false;
2075  }
2076  }
2077  }
2078  }
2079  }
2080 
2081  {
2082  // Send DataChanged before moving. We then can detect
2083  // which objects are still in the range.
2084  // After the move they could come before/after the
2085  // Position.
2086  SwDataChanged aTmp( rPam );
2087  }
2088 
2089  SwNodeIndex aIdx( nOffset > 0 ? pEnd->nNode : pStt->nNode, nOffs );
2090  SwNodeRange aMvRg( pStt->nNode, 0, pEnd->nNode, +1 );
2091 
2092  SwRangeRedline* pOwnRedl = nullptr;
2093  if( getIDocumentRedlineAccess().IsRedlineOn() )
2094  {
2095  // If the range is completely in the own Redline, we can move it!
2096  SwRedlineTable::size_type nRedlPos = getIDocumentRedlineAccess().GetRedlinePos( pStt->nNode.GetNode(), RedlineType::Insert );
2097  if( SwRedlineTable::npos != nRedlPos )
2098  {
2100  const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
2101  SwRangeRedline aTmpRedl( RedlineType::Insert, rPam );
2102  const SwContentNode* pCEndNd = pEnd->nNode.GetNode().GetContentNode();
2103  // Is completely in the range and is the own Redline too?
2104  if( aTmpRedl.IsOwnRedline( *pTmp ) &&
2105  (pRStt->nNode < pStt->nNode ||
2106  (pRStt->nNode == pStt->nNode && !pRStt->nContent.GetIndex()) ) &&
2107  (pEnd->nNode < pREnd->nNode ||
2108  (pEnd->nNode == pREnd->nNode &&
2109  pCEndNd ? pREnd->nContent.GetIndex() == pCEndNd->Len()
2110  : !pREnd->nContent.GetIndex() )) )
2111  {
2112  pOwnRedl = pTmp;
2113  if( nRedlPos + 1 < getIDocumentRedlineAccess().GetRedlineTable().size() )
2114  {
2115  pTmp = getIDocumentRedlineAccess().GetRedlineTable()[ nRedlPos+1 ];
2116  if( *pTmp->Start() == *pREnd )
2117  // then don't!
2118  pOwnRedl = nullptr;
2119  }
2120 
2121  if( pOwnRedl &&
2122  ( pRStt->nNode > aIdx || aIdx > pREnd->nNode ))
2123  {
2124  // it's not in itself, so don't move it
2125  pOwnRedl = nullptr;
2126  }
2127  }
2128  }
2129 
2130  if( !pOwnRedl )
2131  {
2133 
2134  // First the Insert, then the Delete
2135  SwPosition aInsPos( aIdx );
2136  aInsPos.nContent.Assign( aIdx.GetNode().GetContentNode(), 0 );
2137 
2138  SwPaM aPam( pStt->nNode, 0, aMvRg.aEnd, 0 );
2139 
2140  SwPaM& rOrigPam(rPam);
2141  rOrigPam.DeleteMark();
2142  rOrigPam.GetPoint()->nNode = aIdx.GetIndex() - 1;
2143  rOrigPam.GetPoint()->nContent.Assign( rOrigPam.GetContentNode(), 0 );
2144 
2145  bool bDelLastPara = !aInsPos.nNode.GetNode().IsContentNode();
2146 
2147  /* When copying to a non-content node Copy will
2148  insert a paragraph before that node and insert before
2149  that inserted node. Copy creates an SwUndoInserts that
2150  does not cover the extra paragraph. Thus we insert the
2151  extra paragraph ourselves, _with_ correct undo
2152  information. */
2153  if (bDelLastPara)
2154  {
2155  /* aInsPos points to the non-content node. Move it to
2156  the previous content node. */
2157  SwPaM aInsPam(aInsPos);
2158  const bool bMoved = aInsPam.Move(fnMoveBackward);
2159  OSL_ENSURE(bMoved, "No content node found!");
2160 
2161  if (bMoved)
2162  {
2163  /* Append the new node after the content node
2164  found. The new position to insert the moved
2165  paragraph at is before the inserted
2166  paragraph. */
2168  aInsPos = *aInsPam.GetPoint();
2169  }
2170  }
2171 
2172  --aIdx; // move before insertion
2173 
2175 
2176  // now delete all the delete redlines that were copied
2177 #ifndef NDEBUG
2178  size_t nRedlines(getIDocumentRedlineAccess().GetRedlineTable().size());
2179 #endif
2180  if (nOffset > 0)
2181  assert(aPam.End()->nNode.GetIndex() - aPam.Start()->nNode.GetIndex() + nOffset == aInsPos.nNode.GetIndex() - aPam.End()->nNode.GetIndex());
2182  else
2183  assert(aPam.Start()->nNode.GetIndex() - aPam.End()->nNode.GetIndex() + nOffset == aInsPos.nNode.GetIndex() - aPam.End()->nNode.GetIndex());
2185  getIDocumentRedlineAccess().GetRedline(*aPam.End(), &i);
2186  for ( ; 0 < i; --i)
2187  { // iterate backwards and offset via the start nodes difference
2188  SwRangeRedline const*const pRedline = getIDocumentRedlineAccess().GetRedlineTable()[i - 1];
2189  if (*pRedline->End() < *aPam.Start())
2190  {
2191  break;
2192  }
2193  if (pRedline->GetType() == RedlineType::Delete)
2194  {
2195  assert(*aPam.Start() <= *pRedline->Start()); // caller's fault
2196  SwRangeRedline* pNewRedline;
2197  {
2198  SwPaM pam(*pRedline, nullptr);
2199  sal_uLong const nCurrentOffset(
2200  aIdx.GetIndex() + 1 - aPam.Start()->nNode.GetIndex());
2201  pam.GetPoint()->nNode += nCurrentOffset;
2203  pam.GetMark()->nNode += nCurrentOffset;
2205 
2206  pNewRedline = new SwRangeRedline( RedlineType::Delete, pam );
2207  }
2208  // note: effectively this will DeleteAndJoin the pam!
2209  getIDocumentRedlineAccess().AppendRedline(pNewRedline, true);
2210  assert(getIDocumentRedlineAccess().GetRedlineTable().size() <= nRedlines);
2211  }
2212  }
2213 
2214  if( bDelLastPara )
2215  {
2216  // We need to remove the last empty Node again
2217  aIdx = aInsPos.nNode;
2218  SwContentNode* pCNd = SwNodes::GoPrevious( &aInsPos.nNode );
2219  aInsPos.nContent.Assign( pCNd, pCNd ? pCNd->Len() : 0 );
2220 
2221  // All, that are in the to-be-deleted Node, need to be
2222  // moved to the next Node
2224  {
2225  SwPosition* pPos = &pTmp->GetBound();
2226  if( pPos->nNode == aIdx )
2227  {
2228  ++pPos->nNode;
2229  pPos->nContent.Assign( pPos->nNode.GetNode().GetContentNode(),0);
2230  }
2231  pPos = &pTmp->GetBound(false);
2232  if( pPos->nNode == aIdx )
2233  {
2234  ++pPos->nNode;
2235  pPos->nContent.Assign( pPos->nNode.GetNode().GetContentNode(),0);
2236  }
2237  }
2238  CorrRel( aIdx, aInsPos );
2239 
2240  if (pCNd)
2241  pCNd->JoinNext();
2242  }
2243 
2244  ++rOrigPam.GetPoint()->nNode;
2245  rOrigPam.GetPoint()->nContent.Assign( rOrigPam.GetContentNode(), 0 );
2246  assert(*aPam.GetMark() < *aPam.GetPoint());
2247  if (aPam.GetPoint()->nNode.GetNode().IsEndNode())
2248  { // ensure redline ends on content node
2249  --aPam.GetPoint()->nNode;
2250  assert(aPam.GetPoint()->nNode.GetNode().IsTextNode());
2251  SwTextNode *const pNode(aPam.GetPoint()->nNode.GetNode().GetTextNode());
2252  aPam.GetPoint()->nContent.Assign(pNode, pNode->Len());
2253  }
2254 
2256  if (GetIDocumentUndoRedo().DoesUndo())
2257  {
2258  // this should no longer happen in calls from the UI but maybe via API
2259  SAL_WARN_IF((eOld & RedlineFlags::ShowMask) != RedlineFlags::ShowMask,
2260  "sw.core", "redlines will be moved in DeleteAndJoin");
2261 
2265  std::make_unique<SwUndoRedlineDelete>(aPam, SwUndoId::DELETE));
2266  }
2267 
2268  SwRangeRedline* pNewRedline = new SwRangeRedline( RedlineType::Delete, aPam );
2269 
2270  // prevent assertion from aPam's target being deleted
2271  // (Alternatively, one could just let aPam go out of scope, but
2272  // that requires touching a lot of code.)
2273  aPam.GetBound().nContent.Assign( nullptr, 0 );
2274  aPam.GetBound(false).nContent.Assign( nullptr, 0 );
2275 
2276  getIDocumentRedlineAccess().AppendRedline( pNewRedline, true );
2277 
2279  aPam.GetBound(false).nContent.Assign(aPam.GetBound(false).nNode.GetNode().GetContentNode(), 0);
2281 
2285 
2286  return true;
2287  }
2288  }
2289 
2290  if( !pOwnRedl && !getIDocumentRedlineAccess().IsIgnoreRedline() && !getIDocumentRedlineAccess().GetRedlineTable().empty() )
2291  {
2292  SwPaM aTemp(aIdx);
2294  }
2295 
2296  sal_uLong nRedlSttNd(0), nRedlEndNd(0);
2297  if( pOwnRedl )
2298  {
2299  const SwPosition *pRStt = pOwnRedl->Start(), *pREnd = pOwnRedl->End();
2300  nRedlSttNd = pRStt->nNode.GetIndex();
2301  nRedlEndNd = pREnd->nNode.GetIndex();
2302  }
2303 
2304  std::unique_ptr<SwUndoMoveNum> pUndo;
2305  sal_uLong nMoved = 0;
2306  if (GetIDocumentUndoRedo().DoesUndo())
2307  {
2308  pUndo.reset(new SwUndoMoveNum( rPam, nOffset, bIsOutlMv ));
2309  nMoved = rPam.End()->nNode.GetIndex() - rPam.Start()->nNode.GetIndex() + 1;
2310  }
2311 
2312  (void) pLayout; // note: move will insert between aIdx-1 and aIdx
2313  assert(!pLayout // check not moving *into* delete redline (caller's fault)
2317 
2318  if( pUndo )
2319  {
2320  // i57907: Under circumstances (sections at the end of a chapter)
2321  // the rPam.Start() is not moved to the new position.
2322  // But aIdx should be at the new end position and as long as the
2323  // number of moved paragraphs is nMoved, I know, where the new
2324  // position is.
2325  pUndo->SetStartNode( aIdx.GetIndex() - nMoved );
2326  GetIDocumentUndoRedo().AppendUndo(std::move(pUndo));
2327  }
2328 
2329  if( pOwnRedl )
2330  {
2331  SwPosition *pRStt = pOwnRedl->Start(), *pREnd = pOwnRedl->End();
2332  if( pRStt->nNode.GetIndex() != nRedlSttNd )
2333  {
2334  pRStt->nNode = nRedlSttNd;
2335  pRStt->nContent.Assign( pRStt->nNode.GetNode().GetContentNode(),0);
2336  }
2337  if( pREnd->nNode.GetIndex() != nRedlEndNd )
2338  {
2339  pREnd->nNode = nRedlEndNd;
2340  SwContentNode* pCNd = pREnd->nNode.GetNode().GetContentNode();
2341  pREnd->nContent.Assign( pCNd, pCNd ? pCNd->Len() : 0 );
2342  }
2343  }
2344 
2346  return true;
2347 }
2348 
2349 bool SwDoc::NumOrNoNum( const SwNodeIndex& rIdx, bool bDel )
2350 {
2351  bool bResult = false;
2352  SwTextNode * pTextNd = rIdx.GetNode().GetTextNode();
2353 
2354  if (pTextNd && pTextNd->GetNumRule() != nullptr &&
2355  (pTextNd->HasNumber() || pTextNd->HasBullet()))
2356  {
2357  if ( !pTextNd->IsCountedInList() == !bDel)
2358  {
2359  bool bOldNum = bDel;
2360  bool bNewNum = !bDel;
2361  pTextNd->SetCountedInList(bNewNum);
2362 
2364 
2365  bResult = true;
2366 
2367  if (GetIDocumentUndoRedo().DoesUndo())
2368  {
2370  std::make_unique<SwUndoNumOrNoNum>(rIdx, bOldNum, bNewNum));
2371  }
2372  }
2373  else if (bDel && pTextNd->GetNumRule(false) &&
2374  pTextNd->GetActualListLevel() >= 0 &&
2375  pTextNd->GetActualListLevel() < MAXLEVEL)
2376  {
2377  SwPaM aPam(*pTextNd);
2378  DelNumRules(aPam);
2379 
2380  bResult = true;
2381  }
2382  }
2383 
2384  return bResult;
2385 }
2386 
2388  SwRootFrame const*const pLayout)
2389 {
2390  SwNumRule* pRet = nullptr;
2391  SwTextNode* pTNd = rPos.nNode.GetNode().GetTextNode();
2392 
2393  if ( pTNd != nullptr )
2394  {
2395  if (pLayout && !sw::IsParaPropsNode(*pLayout, *pTNd))
2396  {
2397  pTNd = static_cast<SwTextFrame*>(pTNd->getLayoutFrame(pLayout))->GetMergedPara()->pParaPropsNode;
2398  rPos.nNode = *pTNd;
2399  rPos.nContent.Assign(pTNd, 0);
2400  }
2401  pRet = pTNd->GetNumRule();
2402  }
2403 
2404  return pRet;
2405 }
2406 
2407 sal_uInt16 SwDoc::FindNumRule( const OUString& rName ) const
2408 {
2409  for( sal_uInt16 n = mpNumRuleTable->size(); n; )
2410  if( (*mpNumRuleTable)[ --n ]->GetName() == rName )
2411  return n;
2412 
2413  return USHRT_MAX;
2414 }
2415 
2416 SwNumRule* SwDoc::FindNumRulePtr( const OUString& rName ) const
2417 {
2418  SwNumRule * pResult = maNumRuleMap[rName];
2419 
2420  if ( !pResult )
2421  {
2422  for (size_t n = 0; n < mpNumRuleTable->size(); ++n)
2423  {
2424  if ((*mpNumRuleTable)[n]->GetName() == rName)
2425  {
2426  pResult = (*mpNumRuleTable)[n];
2427 
2428  break;
2429  }
2430  }
2431  }
2432 
2433  return pResult;
2434 }
2435 
2437 {
2438  if ((SAL_MAX_UINT16 - 1) <= mpNumRuleTable->size())
2439  {
2440  OSL_ENSURE(false, "SwDoc::AddNumRule: table full.");
2441  abort(); // this should never happen on real documents
2442  }
2443  mpNumRuleTable->push_back(pRule);
2444  maNumRuleMap[pRule->GetName()] = pRule;
2445  pRule->SetNumRuleMap(&maNumRuleMap);
2446 
2448 }
2449 
2450 sal_uInt16 SwDoc::MakeNumRule( const OUString &rName,
2451  const SwNumRule* pCpy,
2452  bool bBroadcast,
2453  const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode )
2454 {
2455  SwNumRule* pNew;
2456  if( pCpy )
2457  {
2458  pNew = new SwNumRule( *pCpy );
2459 
2461 
2462  if( pNew->GetName() != rName )
2463  {
2464  pNew->SetPoolFormatId( USHRT_MAX );
2465  pNew->SetPoolHelpId( USHRT_MAX );
2466  pNew->SetPoolHlpFileId( UCHAR_MAX );
2467  pNew->SetDefaultListId( OUString() );
2468  }
2469  pNew->CheckCharFormats( this );
2470  }
2471  else
2472  {
2473  pNew = new SwNumRule( GetUniqueNumRuleName( &rName ),
2474  eDefaultNumberFormatPositionAndSpaceMode );
2475  }
2476 
2477  sal_uInt16 nRet = mpNumRuleTable->size();
2478 
2479  AddNumRule(pNew);
2480 
2481  if (GetIDocumentUndoRedo().DoesUndo())
2482  {
2484  std::make_unique<SwUndoNumruleCreate>(pNew, this));
2485  }
2486 
2487  if (bBroadcast)
2488  BroadcastStyleOperation(pNew->GetName(), SfxStyleFamily::Pseudo,
2489  SfxHintId::StyleSheetCreated);
2490 
2491  return nRet;
2492 }
2493 
2494 OUString SwDoc::GetUniqueNumRuleName( const OUString* pChkStr, bool bAutoNum ) const
2495 {
2496  // If we got pChkStr, then the caller expects that in case it's not yet
2497  // used, it'll be returned.
2498  if( IsInMailMerge() && !pChkStr )
2499  {
2500  OUString newName = "MailMergeNumRule"
2501  + OStringToOUString( DateTimeToOString( DateTime( DateTime::SYSTEM )), RTL_TEXTENCODING_ASCII_US )
2502  + OUString::number( mpNumRuleTable->size() + 1 );
2503  return newName;
2504  }
2505 
2506  OUString aName;
2507  if( bAutoNum )
2508  {
2509  static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != nullptr);
2510 
2511  if (bHack)
2512  {
2513  static sal_Int64 nIdCounter = SAL_CONST_INT64(8000000000);
2514  aName = OUString::number(nIdCounter++);
2515  }
2516  else
2517  {
2518  unsigned int const n(comphelper::rng::uniform_uint_distribution(0,
2519  std::numeric_limits<unsigned int>::max()));
2520  aName = OUString::number(n);
2521  }
2522  if( pChkStr && pChkStr->isEmpty() )
2523  pChkStr = nullptr;
2524  }
2525  else if( pChkStr && !pChkStr->isEmpty() )
2526  aName = *pChkStr;
2527  else
2528  {
2529  pChkStr = nullptr;
2530  aName = SwResId( STR_NUMRULE_DEFNAME );
2531  }
2532 
2533  sal_uInt16 nNum(0), nTmp, nFlagSize = ( mpNumRuleTable->size() / 8 ) +2;
2534  std::unique_ptr<sal_uInt8[]> pSetFlags(new sal_uInt8[ nFlagSize ]);
2535  memset( pSetFlags.get(), 0, nFlagSize );
2536 
2537  sal_Int32 nNmLen = aName.getLength();
2538  if( !bAutoNum && pChkStr )
2539  {
2540  while( nNmLen-- && '0' <= aName[nNmLen] && aName[nNmLen] <= '9' )
2541  ; //nop
2542 
2543  if( ++nNmLen < aName.getLength() )
2544  {
2545  aName = aName.copy(0, nNmLen );
2546  pChkStr = nullptr;
2547  }
2548  }
2549 
2550  for( auto const & pNumRule: *mpNumRuleTable )
2551  if( nullptr != pNumRule )
2552  {
2553  const OUString sNm = pNumRule->GetName();
2554  if( sNm.startsWith( aName ) )
2555  {
2556  // Determine Number and set the Flag
2557  nNum = static_cast<sal_uInt16>(sNm.copy( nNmLen ).toInt32());
2558  if( nNum-- && nNum < mpNumRuleTable->size() )
2559  pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
2560  }
2561  if( pChkStr && *pChkStr==sNm )
2562  pChkStr = nullptr;
2563  }
2564 
2565  if( !pChkStr )
2566  {
2567  // All Numbers have been flagged accordingly, so identify the right Number
2568  nNum = mpNumRuleTable->size();
2569  for( sal_uInt16 n = 0; n < nFlagSize; ++n )
2570  {
2571  nTmp = pSetFlags[ n ];
2572  if( 0xff != nTmp )
2573  {
2574  // identify the Number
2575  nNum = n * 8;
2576  while( nTmp & 1 )
2577  {
2578  ++nNum;
2579  nTmp >>= 1;
2580  }
2581  break;
2582  }
2583  }
2584  }
2585  if( pChkStr && !pChkStr->isEmpty() )
2586  return *pChkStr;
2587  return aName + OUString::number( ++nNum );
2588 }
2589 
2591 {
2592  const SwNumRuleTable& rNmTable = GetNumRuleTable();
2593  for( size_t n = 0; n < rNmTable.size(); ++n )
2594  if( rNmTable[ n ]->IsInvalidRule() )
2595  rNmTable[ n ]->Validate();
2596 }
2597 
2598 void SwDoc::MarkListLevel( const OUString& sListId,
2599  const int nListLevel,
2600  const bool bValue )
2601 {
2602  SwList* pList = getIDocumentListsAccess().getListByName( sListId );
2603 
2604  if ( pList )
2605  {
2606  // Set new marked list level and notify all affected nodes of the changed mark.
2607  pList->MarkListLevel( nListLevel, bValue );
2608  }
2609 }
2610 
2612  SwRootFrame const& rLayout)
2613 {
2614  bool bResult = false;
2615 
2616  const SwTextNode *const pTextNode = sw::GetParaPropsNode(rLayout, rPos.nNode);
2617  if ( pTextNode != nullptr )
2618  {
2619  bResult = pTextNode->IsFirstOfNumRule(rLayout);
2620  }
2621 
2622  return bResult;
2623 }
2624 
2625 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
Starts a section of nodes in the document model.
Definition: node.hxx:303
void ResetAttrs(const SwPaM &rRg, bool bTextAttr=true, const std::set< sal_uInt16 > &rAttrs=std::set< sal_uInt16 >(), const bool bSendDataChangedEvents=true, SwRootFrame const *pLayout=nullptr)
Reset attributes.
Definition: docfmt.cxx:241
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
virtual sal_Int32 Len() const
Definition: node.cxx:1223
SwHistory * GetHistory()
void DeleteMark()
Definition: pam.hxx:177
void SetListRestart(bool bRestart)
Definition: ndtxt.cxx:4116
bool IsInMailMerge() const
Definition: doc.hxx:957
sal_uLong GetIndex() const
Definition: node.hxx:282
int GetAssignedOutlineStyleLevel() const
Definition: fmtcol.cxx:587
sal_uLong Count() const
Definition: ndarr.hxx:142
bool HasBullet() const
Returns if this text node has a bullet.
Definition: ndtxt.cxx:3105
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
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:1790
bool IsSectionNode() const
Definition: node.hxx:644
const SwNodeNum * GetNum(SwRootFrame const *pLayout=nullptr) const
Definition: ndtxt.cxx:3960
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:228
virtual bool SetAttr(const SfxPoolItem &) override
overriding to handle change of certain paragraph attributes
Definition: ndtxt.cxx:4904
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:88
const OUString & GetListId() const
Definition: list.cxx:227
SwNodeIndex nNode
Definition: pam.hxx:37
static bool lcl_IsValidPrevNextNumNode(const SwNodeIndex &rIdx)
Definition: docnum.cxx:1419
void AddToList()
Definition: ndtxt.cxx:4283
std::vector< SwNode * >::difference_type difference_type
void SetPoolHlpFileId(sal_uInt8 nId)
Definition: numrule.hxx:255
SVX_NUM_NUMBER_NONE
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:275
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
void StopNumRuleAnimations(OutputDevice *)
Definition: docnum.cxx:1146
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:192
constexpr TypedWhichId< SfxInt16Item > RES_PARATR_LIST_RESTARTVALUE(85)
Definition: list.hxx:35
bool IsAutoRule() const
Definition: numrule.hxx:227
bool NumOrNoNum(const SwNodeIndex &rIdx, bool bDel=false)
Definition: docnum.cxx:2349
Pos1 completely contained in Pos2.
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1190
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:4390
Definition: doc.hxx:184
TElementType * Next()
Definition: calbck.hxx:351
void SetContinusNum(bool bFlag)
Definition: numrule.hxx:234
SwSectionNode is derived from SwStartNode.
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1300
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
const OUString & GetName() const
Definition: numrule.hxx:222
OUString GetUniqueNumRuleName(const OUString *pChkStr=nullptr, bool bAutoNum=true) const
Definition: docnum.cxx:2494
SwNumberTree::tNumberVector GetNumberVector() const
Returns level numbers of this node.
SwPosition & GetBound(bool bOne=true)
Definition: pam.hxx:245
Dialog to specify the properties of date form field.
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:143
bool NumUpDown(const SwPaM &, bool bDown, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:1712
std::unordered_map< OUString, SwNumRule * > maNumRuleMap
Definition: doc.hxx:267
void UpdateOutlineIdx(const SwNode &)
Update all OutlineNodes starting from Node.
Definition: ndnum.cxx:75
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:314
bool HasNumber() const
Returns if this text node has a number.
Definition: ndtxt.cxx:3088
bool IsListRestart() const
Definition: ndtxt.cxx:4132
The root element of a Writer document layout.
Definition: rootfrm.hxx:80
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4109
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4025
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:356
bool IsOwnRedline(const SwRangeRedline &rRedl) const
Definition: redline.hxx:241
sal_uInt16 sal_Unicode
bool IsAssignedToListLevelOfOutlineStyle() const
Definition: fmtcol.hxx:109
SwNodeType GetNodeType() const
Definition: node.hxx:144
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:2387
bool NoNum(const SwPaM &)
Definition: docnum.cxx:1301
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:425
check if target position is in fly anchored at source range
std::unique_ptr< SwNumRuleTable > mpNumRuleTable
Definition: doc.hxx:264
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:624
Pos2 completely contained in Pos1.
void MarkListLevel(const int nListLevel, const bool bValue)
Definition: list.cxx:263
o3tl::sorted_vector< SwRootFrame * > GetAllLayouts()
Definition: doclay.cxx:1670
void SetCountedInList(bool bCounted)
Definition: ndtxt.cxx:4237
void GotoNextLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1474
Pos1 before Pos2.
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:154
bool isdigitAsciiString(const OString &rString)
size_type size() const
virtual bool DoesUndo() const =0
Is Undo enabled?
void SetPoolFormatId(sal_uInt16 nId)
Definition: numrule.hxx:249
const char * sName
void CheckCharFormats(SwDoc *pDoc)
Tests whether the CharFormats are from the given doc and copies them if appropriate.
Definition: number.cxx:514
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:163
bool IsContinusNum() const
Definition: numrule.hxx:233
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:628
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:443
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:501
virtual SwRedlineTable::size_type GetRedlinePos(const SwNode &rNode, RedlineType nType) const =0
std::unique_ptr< SwTextFormatColls > mpTextFormatCollTable
Definition: doc.hxx:241
SwNumRule * FindNumRulePtr(const OUString &rName) const
Definition: docnum.cxx:2416
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:2436
virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Opens undo block.
void MakeUniqueNumRules(const SwPaM &rPaM)
Definition: docnum.cxx:1237
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:131
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:4030
TElementType * First()
Definition: calbck.hxx:343
SwContentNode * GetContentNode()
Definition: node.hxx:615
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
SwDoc * GetDoc() const
Definition: pam.hxx:243
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
void UpdateNumRule()
Definition: docnum.cxx:2590
bool IsEnumeration() const
Definition: number.cxx:228
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:3922
static OUString GetOutlineRuleName()
Definition: number.cxx:73
void SetRuleType(SwNumRuleType eNew)
Definition: numrule.hxx:210
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2806
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:393
virtual void deleteListForListStyle(const OUString &rListStyleName)=0
bool IsItemize() const
Definition: number.cxx:236
size
SwNumRule * mpOutlineRule
Definition: doc.hxx:250
void SetPoolHelpId(sal_uInt16 nId)
Definition: numrule.hxx:253
Marks a node in the document model.
Definition: ndindex.hxx:31
bool IsEndNode() const
Definition: node.hxx:632
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:231
OUString newName(const OUString &aNewPrefix, const OUString &aOldPrefix, const OUString &old_Name)
void GetTextNodeList(SwNumRule::tTextNodeList &rTextNodeList) const
Definition: number.cxx:122
OUString SwResId(const char *pId)
Definition: swmodule.cxx:165
SwStartNodeType GetStartNodeType() const
Definition: node.hxx:320
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:218
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
bool MoveParagraphImpl(SwPaM &, long nOffset, bool bIsOutlMv, SwRootFrame const *)
Definition: docnum.cxx:1937
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:78
void CorrRel(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset=0, bool bMoveCursor=false)
Definition: doccorr.cxx:304
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:78
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
virtual bool SplitRedline(const SwPaM &rPam)=0
void SetAttrListLevel(int nLevel)
Sets the list level of this text node.
Definition: ndtxt.cxx:4079
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:334
void Set(sal_uInt16 i, const SwNumFormat *)
Definition: number.cxx:588
void SetInvalidRule(bool bFlag)
Definition: number.cxx:907
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:3376
bool GotoOutline(SwPosition &rPos, const OUString &rName, SwRootFrame const *=nullptr) const
Definition: docnum.cxx:723
#define SAL_WARN_IF(condition, area, stream)
void ChkCondColl()
Definition: node.cxx:2002
static void lcl_ChgNumRule(SwDoc &rDoc, const SwNumRule &rRule)
Definition: docnum.cxx:788
SwNumberTree::tSwNumTreeNumber GetAttrListRestartValue() const
Definition: ndtxt.cxx:4186
void SetDefaultListId(const OUString &sDefaultListId)
Definition: numrule.hxx:188
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:2598
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:1063
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 MoveParagraph(SwPaM &, long nOffset, bool bIsOutlMv=false)
Move selected paragraphs (not only numberings) according to offsets.
Definition: docnum.cxx:1828
bool IsCountedInList() const
Definition: ndtxt.cxx:4252
bool IsUsed(const SwModify &) const
Definition: poolfmt.cxx:84
constexpr TypedWhichId< SfxBoolItem > RES_PARATR_LIST_ISCOUNTED(86)
SwNodes & GetNodes()
Definition: doc.hxx:403
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:1734
static bool GotoNextNum(SwPosition &, SwRootFrame const *pLayout, bool bOverUpper=true, sal_uInt8 *pUpper=nullptr, sal_uInt8 *pLower=nullptr)
Definition: docnum.cxx:1620
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:2450
constexpr TypedWhichId< SwConditionTextFormatColl > RES_CONDTXTFMTCOLL(158)
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
bool IsFirstOfNumRule(SwRootFrame const &rLayout) const
Definition: ndtxt.cxx:4361
bool IsParaPropsNode(SwRootFrame const &rLayout, SwTextNode const &rNode)
Definition: txtfrm.cxx:307
virtual SwContentNode * JoinNext()
Definition: node.cxx:1506
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:417
sal_Int32 GetFirstLineOffset() const
static bool IsFirstOfNumRuleAtPos(const SwPosition &rPos, SwRootFrame const &rLayout)
Definition: docnum.cxx:2611
static bool GotoPrevNum(SwPosition &, SwRootFrame const *pLayout, bool bOverUpper=true)
Definition: docnum.cxx:1706
std::vector< SwTextNode * > tTextNodeList
Definition: numrule.hxx:96
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:352
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).
sal_uInt16 FindNumRule(const OUString &rName) const
Definition: docnum.cxx:2407
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:628
virtual RedlineFlags GetRedlineFlags() const =0
Query the currently set redline mode.
bool IsTableNode() const
Definition: node.hxx:640
SwFormatColl * GetFormatColl() const
Definition: node.hxx:447
bool IsInList() const
Definition: ndtxt.cxx:4356
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:475
Pos1 behind Pos2.
bool DelNumRule(const OUString &rName, bool bBroadCast=false)
Definition: docnum.cxx:1046
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:102
virtual const SwRedlineTable & GetRedlineTable() const =0
virtual bool ResetAttr(sal_uInt16 nWhich1, sal_uInt16 nWhich2=0) override
Definition: ndtxt.cxx:5134
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:1626
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:4181
IDocumentListsAccess const & getIDocumentListsAccess() const
Definition: doc.cxx:292
bool IsTextNode() const
Definition: node.hxx:636
static constexpr size_type npos
Definition: docary.hxx:229
Merge GetRedlineMergeFlag() const
Definition: node.hxx:97
bool OutlineUpDown(const SwPaM &rPam, short nOffset, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:188
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:624
void SetAttrListRestartValue(SwNumberTree::tSwNumTreeNumber nNum)
Definition: ndtxt.cxx:4160
Pos1 overlaps Pos2 at the beginning.
bool IsOutlineRule() const
Definition: numrule.hxx:239
void BroadcastStyleOperation(const OUString &rName, SfxStyleFamily eFamily, SfxHintId nOp)
Definition: docdesc.cxx:600
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:844
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1021
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:79
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:838
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo