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