LibreOffice Module sw (master)  1
ednumber.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 <editsh.hxx>
21 #include <edimp.hxx>
22 #include <doc.hxx>
23 #include <IDocumentUndoRedo.hxx>
24 #include <IDocumentState.hxx>
25 #include <ndtxt.hxx>
26 #include <txtfrm.hxx>
27 #include <swundo.hxx>
28 #include <numrule.hxx>
29 #include <osl/diagnose.h>
30 
32 {
33  for(SwPaM& rTmp : const_cast<SwPaM*>(&rRing)->GetRingContainer())
34  Insert( rTmp.GetMark()->nNode, rTmp.GetPoint()->nNode );
35 }
36 
37 void SwPamRanges::Insert( const SwNodeIndex& rIdx1, const SwNodeIndex& rIdx2 )
38 {
39  SwPamRange aRg( rIdx1.GetIndex(), rIdx2.GetIndex() );
40  if( aRg.nEnd < aRg.nStart )
41  { aRg.nStart = aRg.nEnd; aRg.nEnd = rIdx1.GetIndex(); }
42 
43  o3tl::sorted_vector<SwPamRange>::const_iterator it = maVector.lower_bound(aRg); //search Insert Position
44  size_t nPos = it - maVector.begin();
45  if (!maVector.empty() && (it != maVector.end()) && (*it) == aRg)
46  {
47  // is the one in the Array smaller?
48  SwPamRange const& rTmp = maVector[nPos];
49  if( rTmp.nEnd < aRg.nEnd )
50  {
51  aRg.nEnd = rTmp.nEnd;
52  maVector.erase(maVector.begin() + nPos); // combine
53  }
54  else
55  return; // done, because by precondition everything is combined
56  }
57 
58  bool bEnd;
59  do {
60  bEnd = true;
61 
62  // combine with predecessor?
63  if( nPos > 0 )
64  {
65  SwPamRange const& rTmp = maVector[nPos-1];
66  if( rTmp.nEnd == aRg.nStart
67  || rTmp.nEnd+1 == aRg.nStart )
68  {
69  aRg.nStart = rTmp.nStart;
70  bEnd = false;
71  maVector.erase( maVector.begin() + --nPos ); // combine
72  }
73  // range contained in rTmp?
74  else if( rTmp.nStart <= aRg.nStart && aRg.nEnd <= rTmp.nEnd )
75  return;
76  }
77  // combine with successor?
78  if( nPos < maVector.size() )
79  {
80  SwPamRange const& rTmp = maVector[nPos];
81  if( rTmp.nStart == aRg.nEnd ||
82  rTmp.nStart == aRg.nEnd+1 )
83  {
84  aRg.nEnd = rTmp.nEnd;
85  bEnd = false;
86  maVector.erase( maVector.begin() + nPos ); // combine
87  }
88 
89  // range contained in rTmp?
90  else if( rTmp.nStart <= aRg.nStart && aRg.nEnd <= rTmp.nEnd )
91  return;
92  }
93  } while( !bEnd );
94 
95  maVector.insert( aRg );
96 }
97 
98 SwPaM& SwPamRanges::SetPam( size_t nArrPos, SwPaM& rPam )
99 {
100  assert( nArrPos < Count() );
101  const SwPamRange& rTmp = maVector[ nArrPos ];
102  rPam.GetPoint()->nNode = rTmp.nStart;
103  rPam.GetPoint()->nContent.Assign( rPam.GetContentNode(), 0 );
104  rPam.SetMark();
105  rPam.GetPoint()->nNode = rTmp.nEnd;
106  rPam.GetPoint()->nContent.Assign( rPam.GetContentNode(), 0 );
107  return rPam;
108 }
109 
110 // Rule book for outline numbering
111 
113 {
114  StartAllAction(); // bracketing for updating!
115  GetDoc()->SetOutlineNumRule(rRule);
116  EndAllAction();
117 }
118 
120 {
121  return GetDoc()->GetOutlineNumRule();
122 }
123 
124 // Set if there is no numbering yet, else update.
125 // Works with old and new rules. Update only differences.
126 
127 // paragraphs without numbering, with indentations
129 {
130  StartAllAction();
131 
132  SwPaM* pCursor = GetCursor();
133  if( pCursor->GetNext() != pCursor ) // Multiple selection?
134  {
136  SwPamRanges aRangeArr( *pCursor );
137  SwPaM aPam( *pCursor->GetPoint() );
138  for( size_t n = 0; n < aRangeArr.Count(); ++n )
139  GetDoc()->NoNum( aRangeArr.SetPam( n, aPam ));
141  }
142  else
143  // sw_redlinehide: leave cursor as is, will be split at Point & apply to new node
144  GetDoc()->NoNum( *pCursor );
145 
146  EndAllAction();
147 }
148 
150 {
151  bool bResult = HasNumber();
152  const SwTextNode * pTextNd = sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode);
153  if (!bResult && pTextNd && pTextNd->Len()==0 && !pTextNd->GetNumRule()) {
154  SwPamRanges aRangeArr( *GetCursor() );
155  SwPaM aPam( *GetCursor()->GetPoint() );
156  for( size_t n = 0; n < aRangeArr.Count(); ++n )
157  {
158  aRangeArr.SetPam( n, aPam );
159  {
160  SwNodeOffset nStt = aPam.Start()->nNode.GetIndex(),
161  nEnd = aPam.End()->nNode.GetIndex();
162  for (SwNodeOffset nPos = nStt; nPos<=nEnd; nPos++)
163  {
164  pTextNd = mxDoc->GetNodes()[nPos]->GetTextNode();
165  if (pTextNd)
166  {
167  pTextNd = sw::GetParaPropsNode(*GetLayout(), SwNodeIndex(*pTextNd));
168  }
169  if (pTextNd && pTextNd->Len()!=0)
170  {
171  bResult = pTextNd->HasNumber();
172 
173  // #b6340308# special case: outline numbered, not counted paragraph
174  if ( bResult &&
175  pTextNd->GetNumRule() == GetDoc()->GetOutlineNumRule() &&
176  !pTextNd->IsCountedInList() )
177  {
178  bResult = false;
179  }
180  if (!bResult) {
181  break;
182  }
183  }
184  }
185  }
186  }
187 
188  }
189 
190  return bResult;
191 }
192 
193 // add a new function to determine number on/off status
195 {
196  bool bResult = HasBullet();
197  const SwTextNode * pTextNd = sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode);
198  if (!bResult && pTextNd && pTextNd->Len()==0 && !pTextNd->GetNumRule()) {
199  SwPamRanges aRangeArr( *GetCursor() );
200  SwPaM aPam( *GetCursor()->GetPoint() );
201  for( size_t n = 0; n < aRangeArr.Count(); ++n )
202  {
203  aRangeArr.SetPam( n, aPam );
204  {
205  SwNodeOffset nStt = aPam.Start()->nNode.GetIndex(),
206  nEnd = aPam.End()->nNode.GetIndex();
207  for (SwNodeOffset nPos = nStt; nPos<=nEnd; nPos++)
208  {
209  pTextNd = mxDoc->GetNodes()[nPos]->GetTextNode();
210  if (pTextNd)
211  {
212  pTextNd = sw::GetParaPropsNode(*GetLayout(), SwNodeIndex(*pTextNd));
213  }
214  if (pTextNd && pTextNd->Len()!=0)
215  {
216  bResult = pTextNd->HasBullet();
217 
218  if (!bResult) {
219  break;
220  }
221  }
222  }
223  }
224  }
225  }
226 
227  return bResult;
228 }
229 
230 // -> #i29560#
232 {
233  bool bResult = false;
234 
235  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode);
236 
237  if (pTextNd)
238  {
239  bResult = pTextNd->HasNumber();
240 
241  // special case: outline numbered, not counted paragraph
242  if ( bResult &&
243  pTextNd->GetNumRule() == GetDoc()->GetOutlineNumRule() &&
244  !pTextNd->IsCountedInList() )
245  {
246  bResult = false;
247  }
248  }
249 
250  return bResult;
251 }
252 
254 {
255  bool bResult = false;
256 
257  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode);
258 
259  if (pTextNd)
260  {
261  bResult = pTextNd->HasBullet();
262  }
263 
264  return bResult;
265 }
266 // <- #i29560#
267 
268 // delete, split list
270 {
271  StartAllAction();
272 
273  SwPaM* pCursor = GetCursor();
274  if( pCursor->IsMultiSelection() )
275  {
277  SwPamRanges aRangeArr( *pCursor );
278  SwPaM aPam( *pCursor->GetPoint() );
279  for( size_t n = 0; n < aRangeArr.Count(); ++n )
280  {
281  GetDoc()->DelNumRules(aRangeArr.SetPam( n, aPam ), GetLayout());
282  }
284  }
285  else
286  GetDoc()->DelNumRules(*pCursor, GetLayout());
287 
288  // Call AttrChangeNotify on the UI-side. Should actually be redundant but there was a bug once.
289  CallChgLnk();
290 
291  // Cursor cannot be in front of a label anymore, because numbering/bullet is deleted.
292  SetInFrontOfLabel( false );
293 
295  EndAllAction();
296 }
297 
298 // up- & downgrading
299 void SwEditShell::NumUpDown( bool bDown )
300 {
301  StartAllAction();
302 
303  SwPaM* pCursor = GetCursor();
304  if( !pCursor->IsMultiSelection() )
305  GetDoc()->NumUpDown(*pCursor, bDown, GetLayout());
306  else
307  {
309  SwPamRanges aRangeArr( *pCursor );
310  SwPaM aPam( *pCursor->GetPoint() );
311  for( size_t n = 0; n < aRangeArr.Count(); ++n )
312  GetDoc()->NumUpDown(aRangeArr.SetPam( n, aPam ), bDown, GetLayout());
314  }
316 
317  // #i54693# Update marked numbering levels
318  if ( IsInFrontOfLabel() )
320 
321  CallChgLnk();
322 
323  EndAllAction();
324 }
325 
327 {
328  return SwDoc::IsFirstOfNumRuleAtPos(*GetCursor()->GetPoint(), *GetLayout());
329 }
330 
331 // -> #i23725#, #i90078#
332 void SwEditShell::ChangeIndentOfAllListLevels( const sal_Int32 nDiff )
333 {
334  StartAllAction();
335 
336  const SwNumRule *pCurNumRule = GetNumRuleAtCurrCursorPos();
337  if ( pCurNumRule != nullptr )
338  {
339  SwNumRule aRule(*pCurNumRule);
340  const SwNumFormat& aRootNumFormat(aRule.Get(0));
341  if( nDiff > 0 || aRootNumFormat.GetIndentAt() + nDiff > 0) // fdo#42708
342  {
343  // #i90078#
344  aRule.ChangeIndent( nDiff );
345  }
346  // no start of new list
347  SetCurNumRule( aRule, false );
348  }
349 
350  EndAllAction();
351 }
352 
353 // #i90078#
354 void SwEditShell::SetIndent(short nIndent, const SwPosition & rPos)
355 {
356  StartAllAction();
357 
358  SwPosition pos(rPos);
359  SwNumRule *pCurNumRule = SwDoc::GetNumRuleAtPos(pos, GetLayout());
360 
361  if (pCurNumRule)
362  {
363  SwNumRule aRule(*pCurNumRule);
365  {
367  }
368  else
369  {
370  const SwTextNode* pTextNode = pos.nNode.GetNode().GetTextNode();
371  if ( pTextNode != nullptr
372  && pTextNode->GetActualListLevel() >= 0 )
373  {
374  aRule.SetIndent( nIndent, static_cast< sal_uInt16 >( pTextNode->GetActualListLevel() ) );
375  }
376  }
377 
378  // change numbering rule - changed numbering rule is not applied at <aPaM>
379  SwPaM aPaM(pos);
380  GetDoc()->SetNumRule(aPaM, aRule, false, GetLayout(), OUString(), false);
381  }
382 
383  EndAllAction();
384 }
385 
387 {
388  StartAllAction();
389 
390  SwPaM *pCursor = GetCursor();
391 
392  bool bRet = GetDoc()->MoveParagraph( *pCursor, nOffset );
393 
395  EndAllAction();
396  return bRet;
397 }
398 
400 {
401  int nLevel = 0;
402 
403  SwPaM* pCursor = GetCursor();
404  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->nNode);
405  if (pTextNd)
406  nLevel = pTextNd->GetAttrOutlineLevel();
407  return nLevel;
408 }
409 
411 {
412  SwPaM* pCursor = GetCursor();
413  SwPaM aCursor( *pCursor->Start() );
414  aCursor.SetMark();
415  if( pCursor->HasMark() )
416  *aCursor.GetPoint() = *pCursor->End();
417  SwDoc::GotoNextNum(*aCursor.GetPoint(), GetLayout(), false, &rUpper, &rLower);
418 }
419 
420 bool SwEditShell::MoveNumParas( bool bUpperLower, bool bUpperLeft )
421 {
422  StartAllAction();
423 
424  // On all selections?
425  SwPaM* pCursor = GetCursor();
426  SwPaM aCursor( *pCursor->Start() );
427  aCursor.SetMark();
428 
429  if( pCursor->HasMark() )
430  *aCursor.GetPoint() = *pCursor->End();
431 
432  bool bRet = false;
433  sal_uInt8 nUpperLevel, nLowerLevel;
434  if (SwDoc::GotoNextNum( *aCursor.GetPoint(), GetLayout(), false,
435  &nUpperLevel, &nLowerLevel ))
436  {
437  if( bUpperLower )
438  {
439  // on top of the next numbering
440  SwNodeOffset nOffset(0);
441  const SwNode* pNd;
442 
443  if( bUpperLeft ) // move up
444  {
445  SwPosition aPos( *aCursor.GetMark() );
446  if (SwDoc::GotoPrevNum( aPos, GetLayout(), false ))
447  nOffset = aPos.nNode.GetIndex() -
448  aCursor.GetMark()->nNode.GetIndex();
449  else
450  {
451  SwNodeOffset nStt = aPos.nNode.GetIndex(), nIdx = nStt - 1;
452 
453  if (SwTextNode const*const pStt = aPos.nNode.GetNode().GetTextNode())
454  {
455  std::pair<SwTextNode *, SwTextNode *> nodes(
457  nIdx = nodes.first->GetIndex() - 1;
458  }
459  while( nIdx && (
460  ( pNd = GetDoc()->GetNodes()[ nIdx ])->IsSectionNode() ||
461  ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode())))
462  --nIdx;
463  if( GetDoc()->GetNodes()[ nIdx ]->IsTextNode() )
464  nOffset = nIdx - nStt;
465  }
466  }
467  else // move down
468  {
469  assert(!aCursor.GetNode().IsTextNode()
470  || sw::IsParaPropsNode(*GetLayout(), *aCursor.GetNode().GetTextNode()));
471  const SwNumRule* pOrig = sw::GetParaPropsNode(*GetLayout(), *aCursor.GetNode(false).GetTextNode())->GetNumRule();
472  if( aCursor.GetNode().IsTextNode() &&
473  pOrig == aCursor.GetNode().GetTextNode()->GetNumRule() )
474  {
475  SwNodeOffset nStt = aCursor.GetPoint()->nNode.GetIndex(), nIdx = nStt+1;
476  if (SwTextNode const*const pStt = aCursor.GetPoint()->nNode.GetNode().GetTextNode())
477  {
478  std::pair<SwTextNode *, SwTextNode *> nodes(
480  nIdx = nodes.second->GetIndex() + 1;
481  }
482 
483  while (nIdx < GetDoc()->GetNodes().Count()-1)
484  {
485  pNd = GetDoc()->GetNodes()[ nIdx ];
486 
487  if (pNd->IsSectionNode() ||
488  (pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode()))
489  {
490  ++nIdx;
491  }
492  else if (pNd->IsTextNode())
493  {
494  SwTextNode const*const pTextNode =
496  if (pOrig == pTextNode->GetNumRule()
497  && pTextNode->GetActualListLevel() > nUpperLevel)
498  {
499  std::pair<SwTextNode *, SwTextNode *> nodes(
500  sw::GetFirstAndLastNode(*GetLayout(), *pTextNode));
501  nIdx = nodes.second->GetIndex() + 1;
502  }
503  else
504  {
505  break;
506  }
507  }
508  // #i57856#
509  else
510  {
511  break;
512  }
513  }
514 
515  if( nStt == nIdx || !GetDoc()->GetNodes()[ nIdx ]->IsTextNode() )
516  nOffset = SwNodeOffset(1);
517  else
518  nOffset = nIdx - nStt;
519  }
520  else
521  nOffset = SwNodeOffset(1);
522  }
523 
524  if( nOffset )
525  {
526  aCursor.Move( fnMoveBackward, GoInNode );
527  bRet = GetDoc()->MoveParagraph( aCursor, nOffset );
528  }
529  }
530  else if( (bUpperLeft ? nUpperLevel : nLowerLevel+1) < MAXLEVEL )
531  {
532  aCursor.Move( fnMoveBackward, GoInNode );
533  bRet = GetDoc()->NumUpDown(aCursor, !bUpperLeft, GetLayout());
534  }
535  }
536 
538  EndAllAction();
539  return bRet;
540 }
541 
542 bool SwEditShell::OutlineUpDown( short nOffset )
543 {
544  StartAllAction();
545 
546  bool bRet = true;
547  SwPaM* pCursor = GetCursor();
548  if( !pCursor->IsMultiSelection() )
549  bRet = GetDoc()->OutlineUpDown(*pCursor, nOffset, GetLayout());
550  else
551  {
553  SwPamRanges aRangeArr( *pCursor );
554  SwPaM aPam( *pCursor->GetPoint() );
555  for( size_t n = 0; n < aRangeArr.Count(); ++n )
556  bRet = bRet && GetDoc()->OutlineUpDown(
557  aRangeArr.SetPam(n, aPam), nOffset, GetLayout());
559  }
561  EndAllAction();
562  return bRet;
563 }
564 
566 {
567  StartAllAction();
568  bool bRet = GetDoc()->MoveOutlinePara( *GetCursor(), nOffset );
569  EndAllAction();
570  return bRet;
571 }
572 
573 // Outlines and SubOutline are ReadOnly?
575 {
576  bool bRet = false;
577  const SwNode& rNd = GetCursor()->Start()->nNode.GetNode();
578  if( rNd.IsTextNode() )
579  {
580  const SwOutlineNodes& rOutlNd = GetDoc()->GetNodes().GetOutLineNds();
581  SwNode* pNd = const_cast<SwNode*>(&rNd);
582  bool bFirst = true;
584  int nLvl(0);
585  if( !rOutlNd.Seek_Entry( pNd, &nPos ) && nPos )
586  --nPos;
587 
588  for( ; nPos < rOutlNd.size(); ++nPos )
589  {
590  SwNode* pTmpNd = rOutlNd[ nPos ];
591 
592  if (!sw::IsParaPropsNode(*GetLayout(), *pTmpNd->GetTextNode()))
593  {
594  continue;
595  }
596 
597  int nTmpLvl = pTmpNd->GetTextNode()->GetAttrOutlineLevel();
598 
599  OSL_ENSURE( nTmpLvl >= 0 && nTmpLvl <= MAXLEVEL,
600  "<SwEditShell::IsProtectedOutlinePara()>" );
601 
602  if( bFirst )
603  {
604  nLvl = nTmpLvl;
605  bFirst = false;
606  }
607  else if( nLvl >= nTmpLvl )
608  break;
609 
610  if( pTmpNd->IsProtect() )
611  {
612  bRet = true;
613  break;
614  }
615  }
616  }
617 #if OSL_DEBUG_LEVEL > 0
618  else
619  {
620  OSL_FAIL("Cursor not on an outline node");
621  }
622 #endif
623  return bRet;
624 }
625 
633 static bool lcl_IsOutlineMoveAndCopyable(SwEditShell const& rShell,
634  SwOutlineNodes::size_type const nIdx, bool const bCopy)
635 {
636  const SwNodes& rNds = rShell.GetDoc()->GetNodes();
637  const SwNode* pNd = rNds.GetOutLineNds()[ nIdx ];
638  return pNd->GetIndex() >= rNds.GetEndOfExtras().GetIndex() && // 1) body
639  !pNd->FindTableNode() && // 2) table
640  sw::IsParaPropsNode(*rShell.GetLayout(), *pNd->GetTextNode()) &&
641  ( bCopy || !pNd->IsProtect() ); // 3) write
642 }
643 
645 {
646  return lcl_IsOutlineMoveAndCopyable( *this, nIdx, false );
647 }
648 
650 {
651  return lcl_IsOutlineMoveAndCopyable( *this, nIdx, true );
652 }
653 
655  bool bNumOn,
656  bool bChkStart )
657 {
658  bool bRet = false;
659 
660  if ( !IsMultiSelection()
661  && !HasSelection()
662  && ( !bChkStart || IsSttPara() ) )
663  {
664  StartAllAction();
665  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *GetCursor()->GetPoint()));
666  bRet = GetDoc()->NumOrNoNum(pos.nNode, !bNumOn);
667  EndAllAction();
668  }
669  return bRet;
670 }
671 
672 bool SwEditShell::IsNoNum( bool bChkStart ) const
673 {
674  // a Backspace in the paragraph without number becomes a Delete
675  bool bResult = false;
676 
677  if ( !IsMultiSelection()
678  && !HasSelection()
679  && ( !bChkStart || IsSttPara() ) )
680  {
681  const SwTextNode* pTextNd = sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode);
682  if ( pTextNd != nullptr )
683  {
684  bResult = !pTextNd->IsCountedInList();
685  }
686  }
687 
688  return bResult;
689 }
690 
692 {
693  // return current level where the point of the cursor is
694  sal_uInt8 nLevel = MAXLEVEL;
695 
696  SwPaM* pCursor = GetCursor();
697  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->nNode);
698 
699  OSL_ENSURE( pTextNd, "GetNumLevel() without text node" );
700  if ( pTextNd == nullptr )
701  return nLevel;
702 
703  const SwNumRule* pRule = pTextNd->GetNumRule();
704  if ( pRule != nullptr )
705  {
706  const int nListLevelOfTextNode( pTextNd->GetActualListLevel() );
707  if ( nListLevelOfTextNode >= 0 )
708  {
709  nLevel = static_cast<sal_uInt8>( nListLevelOfTextNode );
710  }
711  }
712 
713  return nLevel;
714 }
715 
717 {
718  SwPosition pos(*GetCursor()->GetPoint());
719  return SwDoc::GetNumRuleAtPos( pos, GetLayout() );
720 }
721 
723 {
724  const SwNumRule* pNumRuleAtCurrentSelection = nullptr;
725 
726  bool bDifferentNumRuleFound = false;
727  for(const SwPaM& rCurrentCursor : GetCursor()->GetRingContainer())
728  {
729  const SwNodeIndex aEndNode = rCurrentCursor.End()->nNode;
730 
731  for ( SwNodeIndex aNode = rCurrentCursor.Start()->nNode; aNode <= aEndNode; ++aNode )
732  {
733  SwPosition pos(aNode);
734  const SwNumRule* pNumRule = SwDoc::GetNumRuleAtPos(pos, GetLayout());
735  if ( pNumRule == nullptr )
736  {
737  continue;
738  }
739  else if ( pNumRule != pNumRuleAtCurrentSelection )
740  {
741  if ( pNumRuleAtCurrentSelection == nullptr )
742  {
743  pNumRuleAtCurrentSelection = pNumRule;
744  }
745  else
746  {
747  pNumRuleAtCurrentSelection = nullptr;
748  bDifferentNumRuleFound = true;
749  break;
750  }
751  }
752  }
753  if(bDifferentNumRuleFound)
754  break;
755  }
756 
757  return pNumRuleAtCurrentSelection;
758 }
759 
761  bool bCreateNewList,
762  const OUString& rContinuedListId,
763  const bool bResetIndentAttrs )
764 {
765  StartAllAction();
766 
768 
769  SwPaM* pCursor = GetCursor();
770  if( IsMultiSelection() )
771  {
772  SwPamRanges aRangeArr( *pCursor );
773  SwPaM aPam( *pCursor->GetPoint() );
774  OUString sContinuedListId(rContinuedListId);
775  for( size_t n = 0; n < aRangeArr.Count(); ++n )
776  {
777  aRangeArr.SetPam( n, aPam );
778  OUString sListId = GetDoc()->SetNumRule( aPam, rRule,
779  bCreateNewList, GetLayout(), sContinuedListId,
780  true, bResetIndentAttrs );
781 
782  //tdf#87548 On creating a new list for a multi-selection only
783  //create a single new list for the multi-selection, not one per selection
784  if (bCreateNewList)
785  {
786  sContinuedListId = sListId;
787  bCreateNewList = false;
788  }
789 
790  GetDoc()->SetCounted(aPam, true, GetLayout());
791  }
792  }
793  else
794  {
795  GetDoc()->SetNumRule( *pCursor, rRule,
796  bCreateNewList, GetLayout(), rContinuedListId,
797  true, bResetIndentAttrs );
798  GetDoc()->SetCounted( *pCursor, true, GetLayout() );
799  }
801 
802  EndAllAction();
803 }
804 
806 {
807  return GetDoc()->GetUniqueNumRuleName();
808 }
809 
811 {
812  StartAllAction();
813  GetDoc()->ChgNumRuleFormats( rRule );
814  EndAllAction();
815 }
816 
817 void SwEditShell::ReplaceNumRule( const OUString& rOldRule, const OUString& rNewRule )
818 {
819  StartAllAction();
820  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *GetCursor()->GetPoint()));
821  GetDoc()->ReplaceNumRule( pos, rOldRule, rNewRule );
822  EndAllAction();
823 }
824 
825 void SwEditShell::SetNumRuleStart( bool bFlag, SwPaM* pPaM )
826 {
827  StartAllAction();
828  SwPaM* pCursor = pPaM ? pPaM : GetCursor();
829  if( pCursor->IsMultiSelection() ) // multiple selection ?
830  {
832  SwPamRanges aRangeArr( *pCursor );
833  SwPaM aPam( *pCursor->GetPoint() );
834  for( size_t n = 0; n < aRangeArr.Count(); ++n )
835  {
836  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *aRangeArr.SetPam( n, aPam ).GetPoint()));
837  GetDoc()->SetNumRuleStart( pos, bFlag );
838  }
840  }
841  else
842  {
843  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *GetCursor()->GetPoint()));
844  GetDoc()->SetNumRuleStart(pos, bFlag);
845  }
846 
847  EndAllAction();
848 }
849 
851 {
852  SwPaM* pCursor = pPaM ? pPaM : GetCursor( );
853  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->nNode);
854  return pTextNd && pTextNd->IsListRestart();
855 }
856 
857 void SwEditShell::SetNodeNumStart( sal_uInt16 nStt )
858 {
859  StartAllAction();
860 
861  SwPaM* pCursor = GetCursor();
862  if( pCursor->IsMultiSelection() ) // multiple selection ?
863  {
865  SwPamRanges aRangeArr( *pCursor );
866  SwPaM aPam( *pCursor->GetPoint() );
867  for( size_t n = 0; n < aRangeArr.Count(); ++n )
868  {
869  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *aRangeArr.SetPam( n, aPam ).GetPoint()));
870  GetDoc()->SetNodeNumStart( pos, nStt );
871  }
873  }
874  else
875  {
876  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *pCursor->GetPoint()));
877  GetDoc()->SetNodeNumStart( pos, nStt );
878  }
879 
880  EndAllAction();
881 }
882 
883 sal_uInt16 SwEditShell::GetNodeNumStart( SwPaM* pPaM ) const
884 {
885  SwPaM* pCursor = pPaM ? pPaM : GetCursor();
886  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->nNode);
887  // correction: check, if list restart value is set at text node and
888  // use new method <SwTextNode::GetAttrListRestartValue()>.
889  // return USHRT_MAX, if no list restart value is found.
890  if ( pTextNd && pTextNd->HasAttrListRestartValue() )
891  {
892  return o3tl::narrowing<sal_uInt16>(pTextNd->GetAttrListRestartValue());
893  }
894  return USHRT_MAX;
895 }
896 
897 const SwNumRule * SwEditShell::SearchNumRule( const bool bNum,
898  OUString& sListId )
899 {
900  return GetDoc()->SearchNumRule( *(GetCursor()->Start()),
901  false/*bForward*/, bNum, false/*bOutline*/, -1/*nNonEmptyAllowe*/,
902  sListId, GetLayout() );
903 }
904 
905 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsNumRuleStart(SwPaM *pPaM=nullptr) const
Definition: ednumber.cxx:850
const_iterator lower_bound(const Value &x) const
bool HasBullet() const
Returns if this text node has a bullet.
Definition: ndtxt.cxx:3142
Marks a position in the document model.
Definition: pam.hxx:36
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2190
bool IsSectionNode() const
Definition: node.hxx:654
bool IsMultiSelection() const
Definition: pam.hxx:273
void GetCurrentOutlineLevels(sal_uInt8 &rUpper, sal_uInt8 &rLower)
Detect highest and lowest level to check moving of outline levels.
Definition: ednumber.cxx:410
OUString GetUniqueNumRuleName() const
Definition: ednumber.cxx:805
const SwNumRule * GetNumRuleAtCurrCursorPos() const
Definition: ednumber.cxx:716
SwNodeIndex nNode
Definition: pam.hxx:38
bool IsSttPara() const
Definition: crsrsh.cxx:1095
std::vector< SwNode * >::difference_type difference_type
SwNodeOffset nStart
Definition: edimp.hxx:32
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:277
virtual void SetModified()=0
Must be called manually at changes of format.
bool NumOrNoNum(const SwNodeIndex &rIdx, bool bDel=false)
Definition: docnum.cxx:2406
bool MoveOutlinePara(const SwPaM &rPam, SwOutlineNodes::difference_type nOffset)
Outline - move up / move down.
Definition: docnum.cxx:451
sal_Int64 n
virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Closes undo block.
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:92
bool SelectionHasNumber() const
Definition: ednumber.cxx:149
SwNode & GetNode() const
Definition: ndindex.hxx:119
void SetNumRuleStart(const SwPosition &rPos, bool bFlag=true)
Definition: docnum.cxx:1016
OUString GetUniqueNumRuleName(const OUString *pChkStr=nullptr, bool bAutoNum=true) const
Definition: docnum.cxx:2551
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:144
bool NumUpDown(const SwPaM &, bool bDown, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:1709
bool HasNumber(SwRootFrame const *pLayout=nullptr) const
Returns if this text node has a number.
Definition: ndtxt.cxx:3126
bool IsListRestart() const
Definition: ndtxt.cxx:4162
void EndAllAction()
Definition: edws.cxx:97
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4139
sal_uInt8 GetNumLevel() const
Definition: ednumber.cxx:691
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4059
bool HasSelection() const
Does the current cursor create a selection?
Definition: crsrsh.cxx:2528
void ChangeIndentOfAllListLevels(sal_Int32 nDiff)
Remove unused default parameter and .
Definition: ednumber.cxx:332
void SetCurNumRule(const SwNumRule &, const bool bCreateNewList, const OUString &sContinuedListId=OUString(), const bool bResetIndentAttrs=false)
Optional parameter (default value false).
Definition: ednumber.cxx:760
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:230
SwNodeOffset nEnd
Definition: edimp.hxx:32
bool IsInFrontOfLabel() const
Definition: crsrsh.cxx:1157
void SetNodeNumStart(sal_uInt16 nStt)
Definition: ednumber.cxx:857
static bool lcl_IsOutlineMoveAndCopyable(SwEditShell const &rShell, SwOutlineNodes::size_type const nIdx, bool const bCopy)
Test whether outline may be moved (bCopy == false) or copied (bCopy == true) Verify these conditions:...
Definition: ednumber.cxx:633
rtl::Reference< SwDoc > mxDoc
The document; never 0.
Definition: viewsh.hxx:171
SwIndex nContent
Definition: pam.hxx:39
static SwNumRule * GetNumRuleAtPos(SwPosition &rPos, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:2444
size_t pos
bool IsProtectedOutlinePara() const
Definition: ednumber.cxx:574
bool IsOutlineMovable(SwOutlineNodes::size_type nIdx) const
May an outline be moved or copied? Check whether it's in text body, not in table, and not read-only (...
Definition: ednumber.cxx:644
bool NoNum(const SwPaM &)
Definition: docnum.cxx:1299
bool IsFirstOfNumRuleAtCursorPos() const
Definition: ednumber.cxx:326
SwDoc * GetDoc() const
Definition: viewsh.hxx:282
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:152
sal_uInt16 GetNodeNumStart(SwPaM *pPaM) const
Definition: ednumber.cxx:883
void DelNumRules()
Delete, split enumeration list.
Definition: ednumber.cxx:269
bool MoveParagraph(SwPaM &, SwNodeOffset nOffset, bool bIsOutlMv=false)
Move selected paragraphs (not only numberings) according to offsets.
Definition: docnum.cxx:1825
size_type size() const
SwPaM * GetNext()
Definition: pam.hxx:265
SwPaM & SetPam(size_t nArrPos, SwPaM &rPam)
Definition: ednumber.cxx:98
void ChgNumRuleFormats(const SwNumRule &rRule)
Definition: ednumber.cxx:810
void SetCounted(const SwPaM &, bool bCounted, SwRootFrame const *pLayout)
Definition: docnum.cxx:1001
void DelNumRules(const SwPaM &, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:1322
void SetNodeNumStart(const SwPosition &rPos, sal_uInt16 nStt)
Definition: docnum.cxx:1038
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
size_t Count() const
Definition: edimp.hxx:50
o3tl::sorted_vector< SwPamRange > maVector
Definition: edimp.hxx:53
virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Opens undo block.
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:959
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:133
const SwPosition * GetPoint() const
Definition: pam.hxx:208
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
SAL_DLLPRIVATE void UpdateMarkedListLevel()
Updates the marked list level according to the cursor.
Definition: crsrsh.cxx:407
Count
SwNodeOffset GetIndex() const
Definition: node.hxx:292
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:206
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2833
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:394
Marks a node in the document model.
Definition: ndindex.hxx:30
bool IsEndNode() const
Definition: node.hxx:642
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:230
ring_container GetRingContainer()
const_iterator end() const
bool empty() const
void SetIndent(const short nNewIndent, const sal_uInt16 nListLevel)
set indent of certain list level to given value
Definition: number.cxx:1019
const SwNumRule * GetOutlineNumRule() const
Definition: ednumber.cxx:119
bool IsProtect() const
Is node in something that is protected (range, frame, table cells ...
Definition: node.cxx:427
const SwPosition * Start() const
Definition: pam.hxx:213
void SetOutlineNumRule(const SwNumRule &rRule)
Definition: docnum.cxx:116
const SwNumRule * GetNumRuleAtCurrentSelection() const
Returns the numbering rule found at the paragraphs of the current selection, if all paragraphs of the...
Definition: ednumber.cxx:722
bool SelectionHasBullet() const
Definition: ednumber.cxx:194
SwTextNode * GetParaPropsNode(SwRootFrame const &rLayout, SwNodeIndex const &rNode)
Definition: txtfrm.cxx:330
void ChangeIndent(const sal_Int32 nDiff)
change indent of all list levels by given difference
Definition: number.cxx:980
bool NumOrNoNum(bool bDelete=false, bool bChkStart=true)
Switch on/off of numbering via Delete/Backspace.
Definition: ednumber.cxx:654
const_iterator begin() const
SwPosition GetParaPropsPos(SwRootFrame const &rLayout, SwPosition const &rPos)
Definition: txtfrm.cxx:344
void CallChgLnk()
Definition: crsrsh.cxx:2537
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:86
bool OutlineUpDown(short nOffset=1)
Definition: ednumber.cxx:542
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
bool HasBullet() const
Definition: ednumber.cxx:253
bool IsMultiSelection() const
Definition: crsrsh.hxx:893
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:195
void ReplaceNumRule(const OUString &rOldRule, const OUString &rNewRule)
Definition: ednumber.cxx:817
SwNumberTree::tSwNumTreeNumber GetAttrListRestartValue() const
Definition: ndtxt.cxx:4215
unsigned char sal_uInt8
void ReplaceNumRule(const SwPosition &rPos, const OUString &rOldRule, const OUString &rNewRule)
Definition: docnum.cxx:1179
bool IsCountedInList() const
Definition: ndtxt.cxx:4276
void SetOutlineNumRule(const SwNumRule &)
Definition: ednumber.cxx:112
SwNodes & GetNodes()
Definition: doc.hxx:408
const SwPosition * End() const
Definition: pam.hxx:218
void SetNumRuleStart(bool bFlag, SwPaM *pCursor)
Set (and query if) a numbering with StartFlag starts at current PointPos.
Definition: ednumber.cxx:825
bool IsNoNum(bool bChkStart=true) const
Definition: ednumber.cxx:672
void NumUpDown(bool bDown=true)
Definition: ednumber.cxx:299
static bool GotoNextNum(SwPosition &, SwRootFrame const *pLayout, bool bOverUpper=true, sal_uInt8 *pUpper=nullptr, sal_uInt8 *pLower=nullptr)
Definition: docnum.cxx:1617
void NoNum()
Paragraphs without enumeration but with indents.
Definition: ednumber.cxx:128
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
bool IsParaPropsNode(SwRootFrame const &rLayout, SwTextNode const &rNode)
Definition: txtfrm.cxx:313
void Insert(const SwNodeIndex &rIdx1, const SwNodeIndex &rIdx2)
Definition: ednumber.cxx:37
static bool IsFirstOfNumRuleAtPos(const SwPosition &rPos, SwRootFrame const &rLayout)
Definition: docnum.cxx:2668
static bool GotoPrevNum(SwPosition &, SwRootFrame const *pLayout, bool bOverUpper=true)
Definition: docnum.cxx:1703
SwPamRanges(const SwPaM &rRing)
Definition: ednumber.cxx:31
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:358
const SwNumRule * SearchNumRule(const bool bNum, OUString &sListId)
Searches for a text node with a numbering rule.
Definition: ednumber.cxx:897
bool MoveParagraph(SwNodeOffset nOffset=SwNodeOffset(1))
Definition: ednumber.cxx:386
bool IsOutlineCopyable(SwOutlineNodes::size_type nIdx) const
Definition: ednumber.cxx:649
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:476
bool Seek_Entry(SwNode *rP, size_type *pnPos) const
Definition: ndnum.cxx:32
int GetCurrentParaOutlineLevel() const
Get Outline level of current paragraph.
Definition: ednumber.cxx:399
bool MoveOutlinePara(SwOutlineNodes::difference_type nOffset)
Definition: ednumber.cxx:565
std::pair< const_iterator, bool > insert(Value &&x)
void SetIndent(short nIndent, const SwPosition &rPos)
Definition: ednumber.cxx:354
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:1623
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:868
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:160
bool HasAttrListRestartValue() const
Definition: ndtxt.cxx:4210
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
bool HasNumber() const
Definition: ednumber.cxx:231
void SetIndentOfFirstListLevelAndChangeOthers(const short nNewIndent)
set indent of first list level to given value and change other list level's indents accordingly ...
Definition: number.cxx:1048
bool IsTextNode() const
Definition: node.hxx:646
SwNumRule * GetNumRule(SwTextFormatColl &rTextFormatColl)
determines the list style, which directly set at the given paragraph style
Definition: fmtcol.cxx:76
bool OutlineUpDown(const SwPaM &rPam, short nOffset, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:203
sal_uInt16 nPos
std::vector< Value >::const_iterator const_iterator
std::pair< SwTextNode *, SwTextNode * > GetFirstAndLastNode(SwRootFrame const &rLayout, SwNodeIndex const &rPos)
Definition: txtfrm.cxx:357
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:864
size_type erase(const Value &x)
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1023
bool SetInFrontOfLabel(bool bNew)
Definition: crsrsh.cxx:1162
void ChgNumRuleFormats(const SwNumRule &rRule)
Definition: docnum.cxx:1100
bool MoveNumParas(bool bUpperLower, bool bUpperLeft)
Definition: ednumber.cxx:420
Base class of the Writer document model elements.
Definition: node.hxx:81