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