1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
23 #include <IDocumentUndoRedo.hxx>
24 #include <IDocumentState.hxx>
28 #include <numrule.hxx>
30 SwPamRanges::SwPamRanges( const SwPaM
& rRing
)
32 for(SwPaM
& rTmp
: const_cast<SwPaM
*>(&rRing
)->GetRingContainer())
33 Insert( rTmp
.GetMark()->nNode
, rTmp
.GetPoint()->nNode
);
36 void SwPamRanges::Insert( const SwNodeIndex
& rIdx1
, const SwNodeIndex
& rIdx2
)
38 SwPamRange
aRg( rIdx1
.GetIndex(), rIdx2
.GetIndex() );
39 if( aRg
.nEnd
< aRg
.nStart
)
40 { aRg
.nStart
= aRg
.nEnd
; aRg
.nEnd
= rIdx1
.GetIndex(); }
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
)
46 // is the one in the Array smaller?
47 SwPamRange
const& rTmp
= maVector
[nPos
];
48 if( rTmp
.nEnd
< aRg
.nEnd
)
51 maVector
.erase(maVector
.begin() + nPos
); // combine
54 return; // done, because by precondition everything is combined
61 // combine with predecessor?
64 SwPamRange
const& rTmp
= maVector
[nPos
-1];
65 if( rTmp
.nEnd
== aRg
.nStart
66 || rTmp
.nEnd
+1 == aRg
.nStart
)
68 aRg
.nStart
= rTmp
.nStart
;
70 maVector
.erase( maVector
.begin() + --nPos
); // combine
72 // range contained in rTmp?
73 else if( rTmp
.nStart
<= aRg
.nStart
&& aRg
.nEnd
<= rTmp
.nEnd
)
76 // combine with successor?
77 if( nPos
< maVector
.size() )
79 SwPamRange
const& rTmp
= maVector
[nPos
];
80 if( rTmp
.nStart
== aRg
.nEnd
||
81 rTmp
.nStart
== aRg
.nEnd
+1 )
85 maVector
.erase( maVector
.begin() + nPos
); // combine
88 // range contained in rTmp?
89 else if( rTmp
.nStart
<= aRg
.nStart
&& aRg
.nEnd
<= rTmp
.nEnd
)
94 maVector
.insert( aRg
);
97 SwPaM
& SwPamRanges::SetPam( size_t nArrPos
, SwPaM
& rPam
)
99 assert( nArrPos
< Count() );
100 const SwPamRange
& rTmp
= maVector
[ nArrPos
];
101 rPam
.GetPoint()->nNode
= rTmp
.nStart
;
102 rPam
.GetPoint()->nContent
.Assign( rPam
.GetContentNode(), 0 );
104 rPam
.GetPoint()->nNode
= rTmp
.nEnd
;
105 rPam
.GetPoint()->nContent
.Assign( rPam
.GetContentNode(), 0 );
109 // Rule book for outline numbering
111 void SwEditShell::SetOutlineNumRule(const SwNumRule
& rRule
)
113 StartAllAction(); // bracketing for updating!
114 GetDoc()->SetOutlineNumRule(rRule
);
118 const SwNumRule
* SwEditShell::GetOutlineNumRule() const
120 return GetDoc()->GetOutlineNumRule();
123 // Set if there is no numbering yet, else update.
124 // Works with old and new rules. Update only differences.
126 // paragraphs without numbering, with indentations
127 void SwEditShell::NoNum()
131 SwPaM
* pCursor
= GetCursor();
132 if( pCursor
->GetNext() != pCursor
) // Multiple selection?
134 GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
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
));
139 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
142 // sw_redlinehide: leave cursor as is, will be split at Point & apply to new node
143 GetDoc()->NoNum( *pCursor
);
148 bool SwEditShell::SelectionHasNumber() const
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
)
157 aRangeArr
.SetPam( n
, aPam
);
159 sal_uInt32 nStt
= aPam
.GetPoint()->nNode
.GetIndex(),
160 nEnd
= aPam
.GetMark()->nNode
.GetIndex();
163 sal_uInt32 nTmp
= nStt
; nStt
= nEnd
; nEnd
= nTmp
;
165 for (sal_uInt32 nPos
= nStt
; nPos
<=nEnd
; nPos
++)
167 pTextNd
= mxDoc
->GetNodes()[nPos
]->GetTextNode();
170 pTextNd
= sw::GetParaPropsNode(*GetLayout(), SwNodeIndex(*pTextNd
));
172 if (pTextNd
&& pTextNd
->Len()!=0)
174 bResult
= pTextNd
->HasNumber();
176 // #b6340308# special case: outline numbered, not counted paragraph
178 pTextNd
->GetNumRule() == GetDoc()->GetOutlineNumRule() &&
179 !pTextNd
->IsCountedInList() )
196 // add a new function to determine number on/off status
197 bool SwEditShell::SelectionHasBullet() const
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
)
206 aRangeArr
.SetPam( n
, aPam
);
208 sal_uInt32 nStt
= aPam
.GetPoint()->nNode
.GetIndex(),
209 nEnd
= aPam
.GetMark()->nNode
.GetIndex();
212 sal_uInt32 nTmp
= nStt
; nStt
= nEnd
; nEnd
= nTmp
;
214 for (sal_uInt32 nPos
= nStt
; nPos
<=nEnd
; nPos
++)
216 pTextNd
= mxDoc
->GetNodes()[nPos
]->GetTextNode();
219 pTextNd
= sw::GetParaPropsNode(*GetLayout(), SwNodeIndex(*pTextNd
));
221 if (pTextNd
&& pTextNd
->Len()!=0)
223 bResult
= pTextNd
->HasBullet();
238 bool SwEditShell::HasNumber() const
240 bool bResult
= false;
242 const SwTextNode
*const pTextNd
= sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode
);
246 bResult
= pTextNd
->HasNumber();
248 // special case: outline numbered, not counted paragraph
250 pTextNd
->GetNumRule() == GetDoc()->GetOutlineNumRule() &&
251 !pTextNd
->IsCountedInList() )
260 bool SwEditShell::HasBullet() const
262 bool bResult
= false;
264 const SwTextNode
*const pTextNd
= sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode
);
268 bResult
= pTextNd
->HasBullet();
275 // delete, split list
276 void SwEditShell::DelNumRules()
280 SwPaM
* pCursor
= GetCursor();
281 if( pCursor
->IsMultiSelection() )
283 GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
284 SwPamRanges
aRangeArr( *pCursor
);
285 SwPaM
aPam( *pCursor
->GetPoint() );
286 for( size_t n
= 0; n
< aRangeArr
.Count(); ++n
)
288 GetDoc()->DelNumRules(aRangeArr
.SetPam( n
, aPam
), GetLayout());
290 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
293 GetDoc()->DelNumRules(*pCursor
, GetLayout());
295 // Call AttrChangeNotify on the UI-side. Should actually be redundant but there was a bug once.
298 // Cursor cannot be in front of a label anymore, because numbering/bullet is deleted.
299 SetInFrontOfLabel( false );
301 GetDoc()->getIDocumentState().SetModified();
306 void SwEditShell::NumUpDown( bool bDown
)
310 SwPaM
* pCursor
= GetCursor();
311 if( !pCursor
->IsMultiSelection() )
312 GetDoc()->NumUpDown(*pCursor
, bDown
, GetLayout());
315 GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
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());
320 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
322 GetDoc()->getIDocumentState().SetModified();
324 // #i54693# Update marked numbering levels
325 if ( IsInFrontOfLabel() )
326 UpdateMarkedListLevel();
333 bool SwEditShell::IsFirstOfNumRuleAtCursorPos() const
335 return SwDoc::IsFirstOfNumRuleAtPos(*GetCursor()->GetPoint(), *GetLayout());
338 // -> #i23725#, #i90078#
339 void SwEditShell::ChangeIndentOfAllListLevels( const sal_Int32 nDiff
)
343 const SwNumRule
*pCurNumRule
= GetNumRuleAtCurrCursorPos();
344 if ( pCurNumRule
!= nullptr )
346 SwNumRule
aRule(*pCurNumRule
);
347 const SwNumFormat
& aRootNumFormat(aRule
.Get(0));
348 if( nDiff
> 0 || aRootNumFormat
.GetIndentAt() + nDiff
> 0) // fdo#42708
351 aRule
.ChangeIndent( nDiff
);
353 // no start of new list
354 SetCurNumRule( aRule
, false );
361 void SwEditShell::SetIndent(short nIndent
, const SwPosition
& rPos
)
365 SwPosition
pos(rPos
);
366 SwNumRule
*pCurNumRule
= SwDoc::GetNumRuleAtPos(pos
, GetLayout());
370 SwNumRule
aRule(*pCurNumRule
);
371 if ( !IsMultiSelection() && IsFirstOfNumRuleAtCursorPos() )
373 aRule
.SetIndentOfFirstListLevelAndChangeOthers( nIndent
);
377 const SwTextNode
* pTextNode
= pos
.nNode
.GetNode().GetTextNode();
378 if ( pTextNode
!= nullptr
379 && pTextNode
->GetActualListLevel() >= 0 )
381 aRule
.SetIndent( nIndent
, static_cast< sal_uInt16
>( pTextNode
->GetActualListLevel() ) );
385 // change numbering rule - changed numbering rule is not applied at <aPaM>
387 GetDoc()->SetNumRule(aPaM
, aRule
, false, GetLayout(), OUString(), false);
393 bool SwEditShell::MoveParagraph( tools::Long nOffset
)
397 SwPaM
*pCursor
= GetCursor();
399 bool bRet
= GetDoc()->MoveParagraph( *pCursor
, nOffset
);
401 GetDoc()->getIDocumentState().SetModified();
406 int SwEditShell::GetCurrentParaOutlineLevel( ) const
410 SwPaM
* pCursor
= GetCursor();
411 const SwTextNode
*const pTextNd
= sw::GetParaPropsNode(*GetLayout(), pCursor
->GetPoint()->nNode
);
413 nLevel
= pTextNd
->GetAttrOutlineLevel();
417 void SwEditShell::GetCurrentOutlineLevels( sal_uInt8
& rUpper
, sal_uInt8
& rLower
)
419 SwPaM
* pCursor
= GetCursor();
420 SwPaM
aCursor( *pCursor
->Start() );
422 if( pCursor
->HasMark() )
423 *aCursor
.GetPoint() = *pCursor
->End();
424 SwDoc::GotoNextNum(*aCursor
.GetPoint(), GetLayout(), false, &rUpper
, &rLower
);
427 bool SwEditShell::MoveNumParas( bool bUpperLower
, bool bUpperLeft
)
431 // On all selections?
432 SwPaM
* pCursor
= GetCursor();
433 SwPaM
aCursor( *pCursor
->Start() );
436 if( pCursor
->HasMark() )
437 *aCursor
.GetPoint() = *pCursor
->End();
440 sal_uInt8 nUpperLevel
, nLowerLevel
;
441 if (SwDoc::GotoNextNum( *aCursor
.GetPoint(), GetLayout(), false,
442 &nUpperLevel
, &nLowerLevel
))
446 // on top of the next numbering
447 tools::Long nOffset
= 0;
450 if( bUpperLeft
) // move up
452 SwPosition
aPos( *aCursor
.GetMark() );
453 if (SwDoc::GotoPrevNum( aPos
, GetLayout(), false ))
454 nOffset
= aPos
.nNode
.GetIndex() -
455 aCursor
.GetMark()->nNode
.GetIndex();
458 sal_uLong nStt
= aPos
.nNode
.GetIndex(), nIdx
= nStt
- 1;
460 if (SwTextNode
const*const pStt
= aPos
.nNode
.GetNode().GetTextNode())
462 std::pair
<SwTextNode
*, SwTextNode
*> nodes(
463 sw::GetFirstAndLastNode(*GetLayout(), *pStt
));
464 nIdx
= nodes
.first
->GetIndex() - 1;
467 ( pNd
= GetDoc()->GetNodes()[ nIdx
])->IsSectionNode() ||
468 ( pNd
->IsEndNode() && pNd
->StartOfSectionNode()->IsSectionNode())))
470 if( GetDoc()->GetNodes()[ nIdx
]->IsTextNode() )
471 nOffset
= nIdx
- nStt
;
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() )
482 sal_uLong nStt
= aCursor
.GetPoint()->nNode
.GetIndex(), nIdx
= nStt
+1;
483 if (SwTextNode
const*const pStt
= aCursor
.GetPoint()->nNode
.GetNode().GetTextNode())
485 std::pair
<SwTextNode
*, SwTextNode
*> nodes(
486 sw::GetFirstAndLastNode(*GetLayout(), *pStt
));
487 nIdx
= nodes
.second
->GetIndex() + 1;
490 while (nIdx
< GetDoc()->GetNodes().Count()-1)
492 pNd
= GetDoc()->GetNodes()[ nIdx
];
494 if (pNd
->IsSectionNode() ||
495 (pNd
->IsEndNode() && pNd
->StartOfSectionNode()->IsSectionNode()))
499 else if (pNd
->IsTextNode())
501 SwTextNode
const*const pTextNode
=
502 sw::GetParaPropsNode(*GetLayout(), SwNodeIndex(*pNd
));
503 if (pOrig
== pTextNode
->GetNumRule()
504 && pTextNode
->GetActualListLevel() > nUpperLevel
)
506 std::pair
<SwTextNode
*, SwTextNode
*> nodes(
507 sw::GetFirstAndLastNode(*GetLayout(), *pTextNode
));
508 nIdx
= nodes
.second
->GetIndex() + 1;
522 if( nStt
== nIdx
|| !GetDoc()->GetNodes()[ nIdx
]->IsTextNode() )
525 nOffset
= nIdx
- nStt
;
533 aCursor
.Move( fnMoveBackward
, GoInNode
);
534 bRet
= GetDoc()->MoveParagraph( aCursor
, nOffset
);
537 else if( (bUpperLeft
? nUpperLevel
: nLowerLevel
+1) < MAXLEVEL
)
539 aCursor
.Move( fnMoveBackward
, GoInNode
);
540 bRet
= GetDoc()->NumUpDown(aCursor
, !bUpperLeft
, GetLayout());
544 GetDoc()->getIDocumentState().SetModified();
549 bool SwEditShell::OutlineUpDown( short nOffset
)
554 SwPaM
* pCursor
= GetCursor();
555 if( !pCursor
->IsMultiSelection() )
556 bRet
= GetDoc()->OutlineUpDown(*pCursor
, nOffset
, GetLayout());
559 GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
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());
565 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
567 GetDoc()->getIDocumentState().SetModified();
572 bool SwEditShell::MoveOutlinePara( SwOutlineNodes::difference_type nOffset
)
575 bool bRet
= GetDoc()->MoveOutlinePara( *GetCursor(), nOffset
);
580 // Outlines and SubOutline are ReadOnly?
581 bool SwEditShell::IsProtectedOutlinePara() const
584 const SwNode
& rNd
= GetCursor()->Start()->nNode
.GetNode();
585 if( rNd
.IsTextNode() )
587 const SwOutlineNodes
& rOutlNd
= GetDoc()->GetNodes().GetOutLineNds();
588 SwNodePtr pNd
= const_cast<SwNodePtr
>(&rNd
);
590 SwOutlineNodes::size_type nPos
;
592 if( !rOutlNd
.Seek_Entry( pNd
, &nPos
) && nPos
)
595 for( ; nPos
< rOutlNd
.size(); ++nPos
)
597 SwNodePtr pTmpNd
= rOutlNd
[ nPos
];
599 if (!sw::IsParaPropsNode(*GetLayout(), *pTmpNd
->GetTextNode()))
604 int nTmpLvl
= pTmpNd
->GetTextNode()->GetAttrOutlineLevel();
606 OSL_ENSURE( nTmpLvl
>= 0 && nTmpLvl
<= MAXLEVEL
,
607 "<SwEditShell::IsProtectedOutlinePara()>" );
614 else if( nLvl
>= nTmpLvl
)
617 if( pTmpNd
->IsProtect() )
624 #if OSL_DEBUG_LEVEL > 0
627 OSL_FAIL("Cursor not on an outline node");
633 /** Test whether outline may be moved (bCopy == false)
634 * or copied (bCopy == true)
635 * Verify these conditions:
636 * 1) outline must be within main body (and not in redline)
637 * 2) outline must not be within table
638 * 3) if bCopy is set, outline must not be write protected
640 static bool lcl_IsOutlineMoveAndCopyable(SwEditShell
const& rShell
,
641 SwOutlineNodes::size_type
const nIdx
, bool const bCopy
)
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
651 bool SwEditShell::IsOutlineMovable( SwOutlineNodes::size_type nIdx
) const
653 return lcl_IsOutlineMoveAndCopyable( *this, nIdx
, false );
656 bool SwEditShell::IsOutlineCopyable( SwOutlineNodes::size_type nIdx
) const
658 return lcl_IsOutlineMoveAndCopyable( *this, nIdx
, true );
661 bool SwEditShell::NumOrNoNum(
667 if ( !IsMultiSelection()
669 && ( !bChkStart
|| IsSttPara() ) )
672 SwPosition
const pos(sw::GetParaPropsPos(*GetLayout(), *GetCursor()->GetPoint()));
673 bRet
= GetDoc()->NumOrNoNum(pos
.nNode
, !bNumOn
);
679 bool SwEditShell::IsNoNum( bool bChkStart
) const
681 // a Backspace in the paragraph without number becomes a Delete
682 bool bResult
= false;
684 if ( !IsMultiSelection()
686 && ( !bChkStart
|| IsSttPara() ) )
688 const SwTextNode
* pTextNd
= sw::GetParaPropsNode(*GetLayout(), GetCursor()->GetPoint()->nNode
);
689 if ( pTextNd
!= nullptr )
691 bResult
= !pTextNd
->IsCountedInList();
698 sal_uInt8
SwEditShell::GetNumLevel() const
700 // return current level where the point of the cursor is
701 sal_uInt8 nLevel
= MAXLEVEL
;
703 SwPaM
* pCursor
= GetCursor();
704 const SwTextNode
*const pTextNd
= sw::GetParaPropsNode(*GetLayout(), pCursor
->GetPoint()->nNode
);
706 OSL_ENSURE( pTextNd
, "GetNumLevel() without text node" );
707 if ( pTextNd
== nullptr )
710 const SwNumRule
* pRule
= pTextNd
->GetNumRule();
711 if ( pRule
!= nullptr )
713 const int nListLevelOfTextNode( pTextNd
->GetActualListLevel() );
714 if ( nListLevelOfTextNode
>= 0 )
716 nLevel
= static_cast<sal_uInt8
>( nListLevelOfTextNode
);
723 const SwNumRule
* SwEditShell::GetNumRuleAtCurrCursorPos() const
725 SwPosition
pos(*GetCursor()->GetPoint());
726 return SwDoc::GetNumRuleAtPos( pos
, GetLayout() );
729 const SwNumRule
* SwEditShell::GetNumRuleAtCurrentSelection() const
731 const SwNumRule
* pNumRuleAtCurrentSelection
= nullptr;
733 bool bDifferentNumRuleFound
= false;
734 for(const SwPaM
& rCurrentCursor
: GetCursor()->GetRingContainer())
736 const SwNodeIndex aEndNode
= rCurrentCursor
.End()->nNode
;
738 for ( SwNodeIndex aNode
= rCurrentCursor
.Start()->nNode
; aNode
<= aEndNode
; ++aNode
)
740 SwPosition
pos(aNode
);
741 const SwNumRule
* pNumRule
= SwDoc::GetNumRuleAtPos(pos
, GetLayout());
742 if ( pNumRule
== nullptr )
746 else if ( pNumRule
!= pNumRuleAtCurrentSelection
)
748 if ( pNumRuleAtCurrentSelection
== nullptr )
750 pNumRuleAtCurrentSelection
= pNumRule
;
754 pNumRuleAtCurrentSelection
= nullptr;
755 bDifferentNumRuleFound
= true;
760 if(bDifferentNumRuleFound
)
764 return pNumRuleAtCurrentSelection
;
767 void SwEditShell::SetCurNumRule( const SwNumRule
& rRule
,
769 const OUString
& rContinuedListId
,
770 const bool bResetIndentAttrs
)
774 GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
776 SwPaM
* pCursor
= GetCursor();
777 if( IsMultiSelection() )
779 SwPamRanges
aRangeArr( *pCursor
);
780 SwPaM
aPam( *pCursor
->GetPoint() );
781 OUString
sContinuedListId(rContinuedListId
);
782 for( size_t n
= 0; n
< aRangeArr
.Count(); ++n
)
784 aRangeArr
.SetPam( n
, aPam
);
785 OUString sListId
= GetDoc()->SetNumRule( aPam
, rRule
,
786 bCreateNewList
, GetLayout(), sContinuedListId
,
787 true, bResetIndentAttrs
);
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
793 sContinuedListId
= sListId
;
794 bCreateNewList
= false;
797 GetDoc()->SetCounted(aPam
, true, GetLayout());
802 GetDoc()->SetNumRule( *pCursor
, rRule
,
803 bCreateNewList
, GetLayout(), rContinuedListId
,
804 true, bResetIndentAttrs
);
805 GetDoc()->SetCounted( *pCursor
, true, GetLayout() );
807 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
812 OUString
SwEditShell::GetUniqueNumRuleName() const
814 return GetDoc()->GetUniqueNumRuleName();
817 void SwEditShell::ChgNumRuleFormats( const SwNumRule
& rRule
)
820 GetDoc()->ChgNumRuleFormats( rRule
);
824 void SwEditShell::ReplaceNumRule( const OUString
& rOldRule
, const OUString
& rNewRule
)
827 SwPosition
const pos(sw::GetParaPropsPos(*GetLayout(), *GetCursor()->GetPoint()));
828 GetDoc()->ReplaceNumRule( pos
, rOldRule
, rNewRule
);
832 void SwEditShell::SetNumRuleStart( bool bFlag
, SwPaM
* pPaM
)
835 SwPaM
* pCursor
= pPaM
? pPaM
: GetCursor();
836 if( pCursor
->IsMultiSelection() ) // multiple selection ?
838 GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
839 SwPamRanges
aRangeArr( *pCursor
);
840 SwPaM
aPam( *pCursor
->GetPoint() );
841 for( size_t n
= 0; n
< aRangeArr
.Count(); ++n
)
843 SwPosition
const pos(sw::GetParaPropsPos(*GetLayout(), *aRangeArr
.SetPam( n
, aPam
).GetPoint()));
844 GetDoc()->SetNumRuleStart( pos
, bFlag
);
846 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
850 SwPosition
const pos(sw::GetParaPropsPos(*GetLayout(), *GetCursor()->GetPoint()));
851 GetDoc()->SetNumRuleStart(pos
, bFlag
);
857 bool SwEditShell::IsNumRuleStart( SwPaM
* pPaM
) const
859 SwPaM
* pCursor
= pPaM
? pPaM
: GetCursor( );
860 const SwTextNode
*const pTextNd
= sw::GetParaPropsNode(*GetLayout(), pCursor
->GetPoint()->nNode
);
861 return pTextNd
&& pTextNd
->IsListRestart();
864 void SwEditShell::SetNodeNumStart( sal_uInt16 nStt
)
868 SwPaM
* pCursor
= GetCursor();
869 if( pCursor
->IsMultiSelection() ) // multiple selection ?
871 GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::START
, nullptr );
872 SwPamRanges
aRangeArr( *pCursor
);
873 SwPaM
aPam( *pCursor
->GetPoint() );
874 for( size_t n
= 0; n
< aRangeArr
.Count(); ++n
)
876 SwPosition
const pos(sw::GetParaPropsPos(*GetLayout(), *aRangeArr
.SetPam( n
, aPam
).GetPoint()));
877 GetDoc()->SetNodeNumStart( pos
, nStt
);
879 GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::END
, nullptr );
883 SwPosition
const pos(sw::GetParaPropsPos(*GetLayout(), *pCursor
->GetPoint()));
884 GetDoc()->SetNodeNumStart( pos
, nStt
);
890 sal_uInt16
SwEditShell::GetNodeNumStart( SwPaM
* pPaM
) const
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() )
899 return static_cast<sal_uInt16
>(pTextNd
->GetAttrListRestartValue());
904 const SwNumRule
* SwEditShell::SearchNumRule( const bool bNum
,
907 return GetDoc()->SearchNumRule( *(GetCursor()->Start()),
908 false/*bForward*/, bNum
, false/*bOutline*/, -1/*nNonEmptyAllowe*/,
909 sListId
, GetLayout() );
912 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */