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  StartAllAction();
130 
131  SwPaM* pCursor = GetCursor();
132  if( pCursor->GetNext() != pCursor ) // Multiple selection?
133  {
135  SwPamRanges aRangeArr( *pCursor );
136  SwPaM aPam( *pCursor->GetPoint() );
137  for( size_t n = 0; n < aRangeArr.Count(); ++n )
138  GetDoc()->NoNum( aRangeArr.SetPam( n, aPam ));
140  }
141  else
142  // sw_redlinehide: leave cursor as is, will be split at Point & apply to new node
143  GetDoc()->NoNum( *pCursor );
144 
145  EndAllAction();
146 }
147 
149 {
150  bool bResult = HasNumber();
151  const SwTextNode * pTextNd = sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode);
152  if (!bResult && pTextNd && pTextNd->Len()==0 && !pTextNd->GetNumRule()) {
153  SwPamRanges aRangeArr( *GetCursor() );
154  SwPaM aPam( *GetCursor()->GetPoint() );
155  for( size_t n = 0; n < aRangeArr.Count(); ++n )
156  {
157  aRangeArr.SetPam( n, aPam );
158  {
159  sal_uInt32 nStt = aPam.GetPoint()->nNode.GetIndex(),
160  nEnd = aPam.GetMark()->nNode.GetIndex();
161  if( nStt > nEnd )
162  {
163  sal_uInt32 nTmp = nStt; nStt = nEnd; nEnd = nTmp;
164  }
165  for (sal_uInt32 nPos = nStt; nPos<=nEnd; nPos++)
166  {
167  pTextNd = mxDoc->GetNodes()[nPos]->GetTextNode();
168  if (pTextNd)
169  {
170  pTextNd = sw::GetParaPropsNode(*GetLayout(), SwNodeIndex(*pTextNd));
171  }
172  if (pTextNd && pTextNd->Len()!=0)
173  {
174  bResult = pTextNd->HasNumber();
175 
176  // #b6340308# special case: outline numbered, not counted paragraph
177  if ( bResult &&
178  pTextNd->GetNumRule() == GetDoc()->GetOutlineNumRule() &&
179  !pTextNd->IsCountedInList() )
180  {
181  bResult = false;
182  }
183  if (!bResult) {
184  break;
185  }
186  }
187  }
188  }
189  }
190 
191  }
192 
193  return bResult;
194 }
195 
196 // add a new function to determine number on/off status
198 {
199  bool bResult = HasBullet();
200  const SwTextNode * pTextNd = sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode);
201  if (!bResult && pTextNd && pTextNd->Len()==0 && !pTextNd->GetNumRule()) {
202  SwPamRanges aRangeArr( *GetCursor() );
203  SwPaM aPam( *GetCursor()->GetPoint() );
204  for( size_t n = 0; n < aRangeArr.Count(); ++n )
205  {
206  aRangeArr.SetPam( n, aPam );
207  {
208  sal_uInt32 nStt = aPam.GetPoint()->nNode.GetIndex(),
209  nEnd = aPam.GetMark()->nNode.GetIndex();
210  if( nStt > nEnd )
211  {
212  sal_uInt32 nTmp = nStt; nStt = nEnd; nEnd = nTmp;
213  }
214  for (sal_uInt32 nPos = nStt; nPos<=nEnd; nPos++)
215  {
216  pTextNd = mxDoc->GetNodes()[nPos]->GetTextNode();
217  if (pTextNd)
218  {
219  pTextNd = sw::GetParaPropsNode(*GetLayout(), SwNodeIndex(*pTextNd));
220  }
221  if (pTextNd && pTextNd->Len()!=0)
222  {
223  bResult = pTextNd->HasBullet();
224 
225  if (!bResult) {
226  break;
227  }
228  }
229  }
230  }
231  }
232  }
233 
234  return bResult;
235 }
236 
237 // -> #i29560#
239 {
240  bool bResult = false;
241 
242  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode);
243 
244  if (pTextNd)
245  {
246  bResult = pTextNd->HasNumber();
247 
248  // special case: outline numbered, not counted paragraph
249  if ( bResult &&
250  pTextNd->GetNumRule() == GetDoc()->GetOutlineNumRule() &&
251  !pTextNd->IsCountedInList() )
252  {
253  bResult = false;
254  }
255  }
256 
257  return bResult;
258 }
259 
261 {
262  bool bResult = false;
263 
264  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode);
265 
266  if (pTextNd)
267  {
268  bResult = pTextNd->HasBullet();
269  }
270 
271  return bResult;
272 }
273 // <- #i29560#
274 
275 // delete, split list
277 {
278  StartAllAction();
279 
280  SwPaM* pCursor = GetCursor();
281  if( pCursor->IsMultiSelection() )
282  {
284  SwPamRanges aRangeArr( *pCursor );
285  SwPaM aPam( *pCursor->GetPoint() );
286  for( size_t n = 0; n < aRangeArr.Count(); ++n )
287  {
288  GetDoc()->DelNumRules(aRangeArr.SetPam( n, aPam ), GetLayout());
289  }
291  }
292  else
293  GetDoc()->DelNumRules(*pCursor, GetLayout());
294 
295  // Call AttrChangeNotify on the UI-side. Should actually be redundant but there was a bug once.
296  CallChgLnk();
297 
298  // Cursor cannot be in front of a label anymore, because numbering/bullet is deleted.
299  SetInFrontOfLabel( false );
300 
302  EndAllAction();
303 }
304 
305 // up- & downgrading
306 void SwEditShell::NumUpDown( bool bDown )
307 {
308  StartAllAction();
309 
310  SwPaM* pCursor = GetCursor();
311  if( !pCursor->IsMultiSelection() )
312  GetDoc()->NumUpDown(*pCursor, bDown, GetLayout());
313  else
314  {
316  SwPamRanges aRangeArr( *pCursor );
317  SwPaM aPam( *pCursor->GetPoint() );
318  for( size_t n = 0; n < aRangeArr.Count(); ++n )
319  GetDoc()->NumUpDown(aRangeArr.SetPam( n, aPam ), bDown, GetLayout());
321  }
323 
324  // #i54693# Update marked numbering levels
325  if ( IsInFrontOfLabel() )
327 
328  CallChgLnk();
329 
330  EndAllAction();
331 }
332 
334 {
335  return SwDoc::IsFirstOfNumRuleAtPos(*GetCursor()->GetPoint(), *GetLayout());
336 }
337 
338 // -> #i23725#, #i90078#
339 void SwEditShell::ChangeIndentOfAllListLevels( const sal_Int32 nDiff )
340 {
341  StartAllAction();
342 
343  const SwNumRule *pCurNumRule = GetNumRuleAtCurrCursorPos();
344  if ( pCurNumRule != nullptr )
345  {
346  SwNumRule aRule(*pCurNumRule);
347  const SwNumFormat& aRootNumFormat(aRule.Get(0));
348  if( nDiff > 0 || aRootNumFormat.GetIndentAt() + nDiff > 0) // fdo#42708
349  {
350  // #i90078#
351  aRule.ChangeIndent( nDiff );
352  }
353  // no start of new list
354  SetCurNumRule( aRule, false );
355  }
356 
357  EndAllAction();
358 }
359 
360 // #i90078#
361 void SwEditShell::SetIndent(short nIndent, const SwPosition & rPos)
362 {
363  StartAllAction();
364 
365  SwPosition pos(rPos);
366  SwNumRule *pCurNumRule = SwDoc::GetNumRuleAtPos(pos, GetLayout());
367 
368  if (pCurNumRule)
369  {
370  SwNumRule aRule(*pCurNumRule);
372  {
374  }
375  else
376  {
377  const SwTextNode* pTextNode = pos.nNode.GetNode().GetTextNode();
378  if ( pTextNode != nullptr
379  && pTextNode->GetActualListLevel() >= 0 )
380  {
381  aRule.SetIndent( nIndent, static_cast< sal_uInt16 >( pTextNode->GetActualListLevel() ) );
382  }
383  }
384 
385  // change numbering rule - changed numbering rule is not applied at <aPaM>
386  SwPaM aPaM(pos);
387  GetDoc()->SetNumRule(aPaM, aRule, false, GetLayout(), OUString(), false);
388  }
389 
390  EndAllAction();
391 }
392 
393 bool SwEditShell::MoveParagraph( long nOffset )
394 {
395  StartAllAction();
396 
397  SwPaM *pCursor = GetCursor();
398 
399  bool bRet = GetDoc()->MoveParagraph( *pCursor, nOffset );
400 
402  EndAllAction();
403  return bRet;
404 }
405 
407 {
408  int nLevel = 0;
409 
410  SwPaM* pCursor = GetCursor();
411  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->nNode);
412  if (pTextNd)
413  nLevel = pTextNd->GetAttrOutlineLevel();
414  return nLevel;
415 }
416 
418 {
419  SwPaM* pCursor = GetCursor();
420  SwPaM aCursor( *pCursor->Start() );
421  aCursor.SetMark();
422  if( pCursor->HasMark() )
423  *aCursor.GetPoint() = *pCursor->End();
424  SwDoc::GotoNextNum(*aCursor.GetPoint(), GetLayout(), false, &rUpper, &rLower);
425 }
426 
427 bool SwEditShell::MoveNumParas( bool bUpperLower, bool bUpperLeft )
428 {
429  StartAllAction();
430 
431  // On all selections?
432  SwPaM* pCursor = GetCursor();
433  SwPaM aCursor( *pCursor->Start() );
434  aCursor.SetMark();
435 
436  if( pCursor->HasMark() )
437  *aCursor.GetPoint() = *pCursor->End();
438 
439  bool bRet = false;
440  sal_uInt8 nUpperLevel, nLowerLevel;
441  if (SwDoc::GotoNextNum( *aCursor.GetPoint(), GetLayout(), false,
442  &nUpperLevel, &nLowerLevel ))
443  {
444  if( bUpperLower )
445  {
446  // on top of the next numbering
447  long nOffset = 0;
448  const SwNode* pNd;
449 
450  if( bUpperLeft ) // move up
451  {
452  SwPosition aPos( *aCursor.GetMark() );
453  if (SwDoc::GotoPrevNum( aPos, GetLayout(), false ))
454  nOffset = aPos.nNode.GetIndex() -
455  aCursor.GetMark()->nNode.GetIndex();
456  else
457  {
458  sal_uLong nStt = aPos.nNode.GetIndex(), nIdx = nStt - 1;
459 
460  if (SwTextNode const*const pStt = aPos.nNode.GetNode().GetTextNode())
461  {
462  std::pair<SwTextNode *, SwTextNode *> nodes(
464  nIdx = nodes.first->GetIndex() - 1;
465  }
466  while( nIdx && (
467  ( pNd = GetDoc()->GetNodes()[ nIdx ])->IsSectionNode() ||
468  ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode())))
469  --nIdx;
470  if( GetDoc()->GetNodes()[ nIdx ]->IsTextNode() )
471  nOffset = nIdx - nStt;
472  }
473  }
474  else // move down
475  {
476  assert(!aCursor.GetNode().IsTextNode()
477  || sw::IsParaPropsNode(*GetLayout(), *aCursor.GetNode().GetTextNode()));
478  const SwNumRule* pOrig = sw::GetParaPropsNode(*GetLayout(), *aCursor.GetNode(false).GetTextNode())->GetNumRule();
479  if( aCursor.GetNode().IsTextNode() &&
480  pOrig == aCursor.GetNode().GetTextNode()->GetNumRule() )
481  {
482  sal_uLong nStt = aCursor.GetPoint()->nNode.GetIndex(), nIdx = nStt+1;
483  if (SwTextNode const*const pStt = aCursor.GetPoint()->nNode.GetNode().GetTextNode())
484  {
485  std::pair<SwTextNode *, SwTextNode *> nodes(
487  nIdx = nodes.second->GetIndex() + 1;
488  }
489 
490  while (nIdx < GetDoc()->GetNodes().Count()-1)
491  {
492  pNd = GetDoc()->GetNodes()[ nIdx ];
493 
494  if (pNd->IsSectionNode() ||
495  (pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode()))
496  {
497  ++nIdx;
498  }
499  else if (pNd->IsTextNode())
500  {
501  SwTextNode const*const pTextNode =
503  if (pOrig == pTextNode->GetNumRule()
504  && pTextNode->GetActualListLevel() > nUpperLevel)
505  {
506  std::pair<SwTextNode *, SwTextNode *> nodes(
507  sw::GetFirstAndLastNode(*GetLayout(), *pTextNode));
508  nIdx = nodes.second->GetIndex() + 1;
509  }
510  else
511  {
512  break;
513  }
514  }
515  // #i57856#
516  else
517  {
518  break;
519  }
520  }
521 
522  if( nStt == nIdx || !GetDoc()->GetNodes()[ nIdx ]->IsTextNode() )
523  nOffset = 1;
524  else
525  nOffset = nIdx - nStt;
526  }
527  else
528  nOffset = 1;
529  }
530 
531  if( nOffset )
532  {
533  aCursor.Move( fnMoveBackward, GoInNode );
534  bRet = GetDoc()->MoveParagraph( aCursor, nOffset );
535  }
536  }
537  else if( (bUpperLeft ? nUpperLevel : nLowerLevel+1) < MAXLEVEL )
538  {
539  aCursor.Move( fnMoveBackward, GoInNode );
540  bRet = GetDoc()->NumUpDown(aCursor, !bUpperLeft, GetLayout());
541  }
542  }
543 
545  EndAllAction();
546  return bRet;
547 }
548 
549 bool SwEditShell::OutlineUpDown( short nOffset )
550 {
551  StartAllAction();
552 
553  bool bRet = true;
554  SwPaM* pCursor = GetCursor();
555  if( !pCursor->IsMultiSelection() )
556  bRet = GetDoc()->OutlineUpDown(*pCursor, nOffset, GetLayout());
557  else
558  {
560  SwPamRanges aRangeArr( *pCursor );
561  SwPaM aPam( *pCursor->GetPoint() );
562  for( size_t n = 0; n < aRangeArr.Count(); ++n )
563  bRet = bRet && GetDoc()->OutlineUpDown(
564  aRangeArr.SetPam(n, aPam), nOffset, GetLayout());
566  }
568  EndAllAction();
569  return bRet;
570 }
571 
573 {
574  StartAllAction();
575  bool bRet = GetDoc()->MoveOutlinePara( *GetCursor(), nOffset );
576  EndAllAction();
577  return bRet;
578 }
579 
580 // Outlines and SubOutline are ReadOnly?
582 {
583  bool bRet = false;
584  const SwNode& rNd = GetCursor()->Start()->nNode.GetNode();
585  if( rNd.IsTextNode() )
586  {
587  const SwOutlineNodes& rOutlNd = GetDoc()->GetNodes().GetOutLineNds();
588  SwNodePtr pNd = const_cast<SwNodePtr>(&rNd);
589  bool bFirst = true;
591  int nLvl(0);
592  if( !rOutlNd.Seek_Entry( pNd, &nPos ) && nPos )
593  --nPos;
594 
595  for( ; nPos < rOutlNd.size(); ++nPos )
596  {
597  SwNodePtr pTmpNd = rOutlNd[ nPos ];
598 
599  if (!sw::IsParaPropsNode(*GetLayout(), *pTmpNd->GetTextNode()))
600  {
601  continue;
602  }
603 
604  int nTmpLvl = pTmpNd->GetTextNode()->GetAttrOutlineLevel();
605 
606  OSL_ENSURE( nTmpLvl >= 0 && nTmpLvl <= MAXLEVEL,
607  "<SwEditShell::IsProtectedOutlinePara()>" );
608 
609  if( bFirst )
610  {
611  nLvl = nTmpLvl;
612  bFirst = false;
613  }
614  else if( nLvl >= nTmpLvl )
615  break;
616 
617  if( pTmpNd->IsProtect() )
618  {
619  bRet = true;
620  break;
621  }
622  }
623  }
624 #if OSL_DEBUG_LEVEL > 0
625  else
626  {
627  OSL_FAIL("Cursor not on an outline node");
628  }
629 #endif
630  return bRet;
631 }
632 
640 static bool lcl_IsOutlineMoveAndCopyable(SwEditShell const& rShell,
641  SwOutlineNodes::size_type const nIdx, bool const bCopy)
642 {
643  const SwNodes& rNds = rShell.GetDoc()->GetNodes();
644  const SwNode* pNd = rNds.GetOutLineNds()[ nIdx ];
645  return pNd->GetIndex() >= rNds.GetEndOfExtras().GetIndex() && // 1) body
646  !pNd->FindTableNode() && // 2) table
647  sw::IsParaPropsNode(*rShell.GetLayout(), *pNd->GetTextNode()) &&
648  ( bCopy || !pNd->IsProtect() ); // 3) write
649 }
650 
652 {
653  return lcl_IsOutlineMoveAndCopyable( *this, nIdx, false );
654 }
655 
657 {
658  return lcl_IsOutlineMoveAndCopyable( *this, nIdx, true );
659 }
660 
662  bool bNumOn,
663  bool bChkStart )
664 {
665  bool bRet = false;
666 
667  if ( !IsMultiSelection()
668  && !HasSelection()
669  && ( !bChkStart || IsSttPara() ) )
670  {
671  StartAllAction();
672  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *GetCursor()->GetPoint()));
673  bRet = GetDoc()->NumOrNoNum(pos.nNode, !bNumOn);
674  EndAllAction();
675  }
676  return bRet;
677 }
678 
679 bool SwEditShell::IsNoNum( bool bChkStart ) const
680 {
681  // a Backspace in the paragraph without number becomes a Delete
682  bool bResult = false;
683 
684  if ( !IsMultiSelection()
685  && !HasSelection()
686  && ( !bChkStart || IsSttPara() ) )
687  {
688  const SwTextNode* pTextNd = sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode);
689  if ( pTextNd != nullptr )
690  {
691  bResult = !pTextNd->IsCountedInList();
692  }
693  }
694 
695  return bResult;
696 }
697 
699 {
700  // return current level where the point of the cursor is
701  sal_uInt8 nLevel = MAXLEVEL;
702 
703  SwPaM* pCursor = GetCursor();
704  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->nNode);
705 
706  OSL_ENSURE( pTextNd, "GetNumLevel() without text node" );
707  if ( pTextNd == nullptr )
708  return nLevel;
709 
710  const SwNumRule* pRule = pTextNd->GetNumRule();
711  if ( pRule != nullptr )
712  {
713  const int nListLevelOfTextNode( pTextNd->GetActualListLevel() );
714  if ( nListLevelOfTextNode >= 0 )
715  {
716  nLevel = static_cast<sal_uInt8>( nListLevelOfTextNode );
717  }
718  }
719 
720  return nLevel;
721 }
722 
724 {
725  SwPosition pos(*GetCursor()->GetPoint());
726  return SwDoc::GetNumRuleAtPos( pos, GetLayout() );
727 }
728 
730 {
731  const SwNumRule* pNumRuleAtCurrentSelection = nullptr;
732 
733  bool bDifferentNumRuleFound = false;
734  for(const SwPaM& rCurrentCursor : GetCursor()->GetRingContainer())
735  {
736  const SwNodeIndex aEndNode = rCurrentCursor.End()->nNode;
737 
738  for ( SwNodeIndex aNode = rCurrentCursor.Start()->nNode; aNode <= aEndNode; ++aNode )
739  {
740  SwPosition pos(aNode);
741  const SwNumRule* pNumRule = SwDoc::GetNumRuleAtPos(pos, GetLayout());
742  if ( pNumRule == nullptr )
743  {
744  continue;
745  }
746  else if ( pNumRule != pNumRuleAtCurrentSelection )
747  {
748  if ( pNumRuleAtCurrentSelection == nullptr )
749  {
750  pNumRuleAtCurrentSelection = pNumRule;
751  }
752  else
753  {
754  pNumRuleAtCurrentSelection = nullptr;
755  bDifferentNumRuleFound = true;
756  break;
757  }
758  }
759  }
760  if(bDifferentNumRuleFound)
761  break;
762  }
763 
764  return pNumRuleAtCurrentSelection;
765 }
766 
768  bool bCreateNewList,
769  const OUString& rContinuedListId,
770  const bool bResetIndentAttrs )
771 {
772  StartAllAction();
773 
775 
776  SwPaM* pCursor = GetCursor();
777  if( IsMultiSelection() )
778  {
779  SwPamRanges aRangeArr( *pCursor );
780  SwPaM aPam( *pCursor->GetPoint() );
781  OUString sContinuedListId(rContinuedListId);
782  for( size_t n = 0; n < aRangeArr.Count(); ++n )
783  {
784  aRangeArr.SetPam( n, aPam );
785  OUString sListId = GetDoc()->SetNumRule( aPam, rRule,
786  bCreateNewList, GetLayout(), sContinuedListId,
787  true, bResetIndentAttrs );
788 
789  //tdf#87548 On creating a new list for a multi-selection only
790  //create a single new list for the multi-selection, not one per selection
791  if (bCreateNewList)
792  {
793  sContinuedListId = sListId;
794  bCreateNewList = false;
795  }
796 
797  GetDoc()->SetCounted(aPam, true, GetLayout());
798  }
799  }
800  else
801  {
802  GetDoc()->SetNumRule( *pCursor, rRule,
803  bCreateNewList, GetLayout(), rContinuedListId,
804  true, bResetIndentAttrs );
805  GetDoc()->SetCounted( *pCursor, true, GetLayout() );
806  }
808 
809  EndAllAction();
810 }
811 
813 {
814  return GetDoc()->GetUniqueNumRuleName();
815 }
816 
818 {
819  StartAllAction();
820  GetDoc()->ChgNumRuleFormats( rRule );
821  EndAllAction();
822 }
823 
824 void SwEditShell::ReplaceNumRule( const OUString& rOldRule, const OUString& rNewRule )
825 {
826  StartAllAction();
827  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *GetCursor()->GetPoint()));
828  GetDoc()->ReplaceNumRule( pos, rOldRule, rNewRule );
829  EndAllAction();
830 }
831 
832 void SwEditShell::SetNumRuleStart( bool bFlag, SwPaM* pPaM )
833 {
834  StartAllAction();
835  SwPaM* pCursor = pPaM ? pPaM : GetCursor();
836  if( pCursor->IsMultiSelection() ) // multiple selection ?
837  {
839  SwPamRanges aRangeArr( *pCursor );
840  SwPaM aPam( *pCursor->GetPoint() );
841  for( size_t n = 0; n < aRangeArr.Count(); ++n )
842  {
843  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *aRangeArr.SetPam( n, aPam ).GetPoint()));
844  GetDoc()->SetNumRuleStart( pos, bFlag );
845  }
847  }
848  else
849  {
850  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *GetCursor()->GetPoint()));
851  GetDoc()->SetNumRuleStart(pos, bFlag);
852  }
853 
854  EndAllAction();
855 }
856 
858 {
859  SwPaM* pCursor = pPaM ? pPaM : GetCursor( );
860  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->nNode);
861  return pTextNd && pTextNd->IsListRestart();
862 }
863 
864 void SwEditShell::SetNodeNumStart( sal_uInt16 nStt )
865 {
866  StartAllAction();
867 
868  SwPaM* pCursor = GetCursor();
869  if( pCursor->IsMultiSelection() ) // multiple selection ?
870  {
872  SwPamRanges aRangeArr( *pCursor );
873  SwPaM aPam( *pCursor->GetPoint() );
874  for( size_t n = 0; n < aRangeArr.Count(); ++n )
875  {
876  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *aRangeArr.SetPam( n, aPam ).GetPoint()));
877  GetDoc()->SetNodeNumStart( pos, nStt );
878  }
880  }
881  else
882  {
883  SwPosition const pos(sw::GetParaPropsPos(*GetLayout(), *pCursor->GetPoint()));
884  GetDoc()->SetNodeNumStart( pos, nStt );
885  }
886 
887  EndAllAction();
888 }
889 
890 sal_uInt16 SwEditShell::GetNodeNumStart( SwPaM* pPaM ) const
891 {
892  SwPaM* pCursor = pPaM ? pPaM : GetCursor();
893  const SwTextNode *const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->nNode);
894  // correction: check, if list restart value is set at text node and
895  // use new method <SwTextNode::GetAttrListRestartValue()>.
896  // return USHRT_MAX, if no list restart value is found.
897  if ( pTextNd && pTextNd->HasAttrListRestartValue() )
898  {
899  return static_cast<sal_uInt16>(pTextNd->GetAttrListRestartValue());
900  }
901  return USHRT_MAX;
902 }
903 
904 const SwNumRule * SwEditShell::SearchNumRule( const bool bNum,
905  OUString& sListId )
906 {
907  return GetDoc()->SearchNumRule( *(GetCursor()->Start()),
908  false/*bForward*/, bNum, false/*bOutline*/, -1/*nNonEmptyAllowe*/,
909  sListId, GetLayout() );
910 }
911 
912 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsNumRuleStart(SwPaM *pPaM=nullptr) const
Definition: ednumber.cxx:857
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:3104
Marks a position in the document model.
Definition: pam.hxx:35
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2087
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:188
void GetCurrentOutlineLevels(sal_uInt8 &rUpper, sal_uInt8 &rLower)
Detect highest and lowest level to check moving of outline levels.
Definition: ednumber.cxx:417
OUString GetUniqueNumRuleName() const
Definition: ednumber.cxx:812
const SwNumRule * GetNumRuleAtCurrCursorPos() const
Definition: ednumber.cxx:723
sal_uLong nEnd
Definition: edimp.hxx:31
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsSttPara() const
Definition: crsrsh.cxx:1092
std::vector< SwNode * >::difference_type difference_type
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:274
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:2349
bool MoveOutlinePara(const SwPaM &rPam, SwOutlineNodes::difference_type nOffset)
Outline - move up / move down.
Definition: docnum.cxx:435
sal_Int64 n
virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Closes undo block.
bool SelectionHasNumber() const
Definition: ednumber.cxx:148
SwNode & GetNode() const
Definition: ndindex.hxx:119
void SetNumRuleStart(const SwPosition &rPos, bool bFlag=true)
Definition: docnum.cxx:1001
OUString GetUniqueNumRuleName(const OUString *pChkStr=nullptr, bool bAutoNum=true) const
Definition: docnum.cxx:2494
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:143
bool NumUpDown(const SwPaM &, bool bDown, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:1712
bool HasNumber() const
Returns if this text node has a number.
Definition: ndtxt.cxx:3087
bool IsListRestart() const
Definition: ndtxt.cxx:4112
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:4089
sal_uInt8 GetNumLevel() const
Definition: ednumber.cxx:698
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4024
bool HasSelection() const
Does the current cursor create a selection?
Definition: crsrsh.cxx:2500
void ChangeIndentOfAllListLevels(sal_Int32 nDiff)
Remove unused default parameter and .
Definition: ednumber.cxx:339
void SetCurNumRule(const SwNumRule &, const bool bCreateNewList, const OUString &sContinuedListId=OUString(), const bool bResetIndentAttrs=false)
Optional parameter (default value false).
Definition: ednumber.cxx:767
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
bool IsInFrontOfLabel() const
Definition: crsrsh.cxx:1154
void SetNodeNumStart(sal_uInt16 nStt)
Definition: ednumber.cxx:864
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:640
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:2387
size_t pos
bool IsProtectedOutlinePara() const
Definition: ednumber.cxx:581
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:651
bool NoNum(const SwPaM &)
Definition: docnum.cxx:1300
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
bool IsFirstOfNumRuleAtCursorPos() const
Definition: ednumber.cxx:333
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
sal_uInt16 GetNodeNumStart(SwPaM *pPaM) const
Definition: ednumber.cxx:890
void DelNumRules()
Delete, split enumeration list.
Definition: ednumber.cxx:276
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:817
void SetCounted(const SwPaM &, bool bCounted, SwRootFrame const *pLayout)
Definition: docnum.cxx:986
void DelNumRules(const SwPaM &, SwRootFrame const *pLayout=nullptr)
Definition: docnum.cxx:1323
void SetNodeNumStart(const SwPosition &rPos, sal_uInt16 nStt)
Definition: docnum.cxx:1023
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:954
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
const SwPosition * GetPoint() const
Definition: pam.hxx:207
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:405
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:393
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2805
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:231
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:962
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:419
const SwPosition * Start() const
Definition: pam.hxx:212
void SetOutlineNumRule(const SwNumRule &rRule)
Definition: docnum.cxx:113
const SwNumRule * GetNumRuleAtCurrentSelection() const
Returns the numbering rule found at the paragraphs of the current selection, if all paragraphs of the...
Definition: ednumber.cxx:729
bool SelectionHasBullet() const
Definition: ednumber.cxx:197
bool ReplaceNumRule(const SwPosition &rPos, const OUString &rOldRule, const OUString &rNewRule)
Definition: docnum.cxx:1164
SwTextNode * GetParaPropsNode(SwRootFrame const &rLayout, SwNodeIndex const &rNode)
Definition: txtfrm.cxx:324
void ChangeIndent(const sal_Int32 nDiff)
change indent of all list levels by given difference
Definition: number.cxx:923
bool NumOrNoNum(bool bDelete=false, bool bChkStart=true)
Switch on/off of numbering via Delete/Backspace.
Definition: ednumber.cxx:661
const_iterator begin() const
SwPosition GetParaPropsPos(SwRootFrame const &rLayout, SwPosition const &rPos)
Definition: txtfrm.cxx:338
void CallChgLnk()
Definition: crsrsh.cxx:2506
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:78
bool OutlineUpDown(short nOffset=1)
Definition: ednumber.cxx:549
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
bool HasBullet() const
Definition: ednumber.cxx:260
bool IsMultiSelection() const
Definition: crsrsh.hxx:888
void ReplaceNumRule(const OUString &rOldRule, const OUString &rNewRule)
Definition: ednumber.cxx:824
SwNumberTree::tSwNumTreeNumber GetAttrListRestartValue() const
Definition: ndtxt.cxx:4166
unsigned char sal_uInt8
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:253
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:4232
void SetOutlineNumRule(const SwNumRule &)
Definition: ednumber.cxx:111
SwNodes & GetNodes()
Definition: doc.hxx:405
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:832
bool IsNoNum(bool bChkStart=true) const
Definition: ednumber.cxx:679
void NumUpDown(bool bDown=true)
Definition: ednumber.cxx:306
static bool GotoNextNum(SwPosition &, SwRootFrame const *pLayout, bool bOverUpper=true, sal_uInt8 *pUpper=nullptr, sal_uInt8 *pLower=nullptr)
Definition: docnum.cxx:1620
void NoNum()
Paragraphs without enumeration but with indents.
Definition: ednumber.cxx:127
bool IsParaPropsNode(SwRootFrame const &rLayout, SwTextNode const &rNode)
Definition: txtfrm.cxx:307
void Insert(const SwNodeIndex &rIdx1, const SwNodeIndex &rIdx2)
Definition: ednumber.cxx:36
static bool IsFirstOfNumRuleAtPos(const SwPosition &rPos, SwRootFrame const &rLayout)
Definition: docnum.cxx:2608
static bool GotoPrevNum(SwPosition &, SwRootFrame const *pLayout, bool bOverUpper=true)
Definition: docnum.cxx:1706
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:350
const SwNumRule * SearchNumRule(const bool bNum, OUString &sListId)
Searches for a text node with a numbering rule.
Definition: ednumber.cxx:904
bool IsOutlineCopyable(SwOutlineNodes::size_type nIdx) const
Definition: ednumber.cxx:656
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:475
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:406
bool MoveOutlinePara(SwOutlineNodes::difference_type nOffset)
Definition: ednumber.cxx:572
std::pair< const_iterator, bool > insert(Value &&x)
void SetIndent(short nIndent, const SwPosition &rPos)
Definition: ednumber.cxx:361
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:853
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:161
bool HasAttrListRestartValue() const
Definition: ndtxt.cxx:4161
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2069
bool HasNumber() const
Definition: ednumber.cxx:238
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:991
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:187
sal_uInt16 nPos
std::vector< Value >::const_iterator const_iterator
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:836
size_type erase(const Value &x)
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1023
bool SetInFrontOfLabel(bool bNew)
Definition: crsrsh.cxx:1159
void ChgNumRuleFormats(const SwNumRule &rRule)
Definition: docnum.cxx:1085
bool MoveNumParas(bool bUpperLower, bool bUpperLeft)
Definition: ednumber.cxx:427
Base class of the Writer document model elements.
Definition: node.hxx:79