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