xref: /trunk/main/sw/source/core/edit/ednumber.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <hintids.hxx>
33 #include <editsh.hxx>
34 #include <edimp.hxx>
35 #include <doc.hxx>
36 #include <IDocumentUndoRedo.hxx>
37 #include <ndtxt.hxx>
38 #include <paratr.hxx>
39 #include <swundo.hxx>
40 #include <numrule.hxx>
41 
42 SV_IMPL_VARARR_SORT( _SwPamRanges, SwPamRange )
43 
44 
45 SwPamRanges::SwPamRanges( const SwPaM& rRing )
46 {
47     const SwPaM* pTmp = &rRing;
48     do {
49         Insert( pTmp->GetMark()->nNode, pTmp->GetPoint()->nNode );
50     } while( &rRing != ( pTmp = (const SwPaM*)pTmp->GetNext() ));
51 }
52 
53 
54 void SwPamRanges::Insert( const SwNodeIndex& rIdx1, const SwNodeIndex& rIdx2 )
55 {
56     SwPamRange aRg( rIdx1.GetIndex(), rIdx2.GetIndex() );
57     if( aRg.nEnd < aRg.nStart )
58     {   aRg.nStart = aRg.nEnd; aRg.nEnd = rIdx1.GetIndex(); }
59 
60     sal_uInt16 nPos = 0;
61     const SwPamRange* pTmp;
62     if( Count() && Seek_Entry( aRg, &nPos ))        // suche Insert Position
63     {
64         // ist der im Array stehende kleiner ??
65         if( ( pTmp = GetData()+ nPos )->nEnd < aRg.nEnd )
66         {
67             aRg.nEnd = pTmp->nEnd;
68             Remove( nPos, 1 );      // zusammenfassen
69         }
70         else
71             return;     // ende, weil schon alle zusammengefasst waren
72     }
73 
74     sal_Bool bEnde;
75     do {
76         bEnde = sal_True;
77 
78         // mit dem Vorgaenger zusammenfassen ??
79         if( nPos > 0 )
80         {
81             if( ( pTmp = GetData()+( nPos-1 ))->nEnd == aRg.nStart
82                 || pTmp->nEnd+1 == aRg.nStart )
83             {
84                 aRg.nStart = pTmp->nStart;
85                 bEnde = sal_False;
86                 Remove( --nPos, 1 );        // zusammenfassen
87             }
88             // SSelection im Bereich ??
89             else if( pTmp->nStart <= aRg.nStart && aRg.nEnd <= pTmp->nEnd )
90                 return;
91         }
92             // mit dem Nachfolger zusammenfassen ??
93         if( nPos < Count() )
94         {
95             if( ( pTmp = GetData() + nPos )->nStart == aRg.nEnd ||
96                 pTmp->nStart == aRg.nEnd+1 )
97             {
98                 aRg.nEnd = pTmp->nEnd;
99                 bEnde = sal_False;
100                 Remove( nPos, 1 );      // zusammenfassen
101             }
102 
103             // SSelection im Bereich ??
104             else if( pTmp->nStart <= aRg.nStart && aRg.nEnd <= pTmp->nEnd )
105                 return;
106         }
107     } while( !bEnde );
108 
109     _SwPamRanges::Insert( aRg );
110 }
111 
112 
113 
114 SwPaM& SwPamRanges::SetPam( sal_uInt16 nArrPos, SwPaM& rPam )
115 {
116     ASSERT_ID( nArrPos < Count(), ERR_VAR_IDX );
117     const SwPamRange& rTmp = *(GetData() + nArrPos );
118     rPam.GetPoint()->nNode = rTmp.nStart;
119     rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), 0 );
120     rPam.SetMark();
121     rPam.GetPoint()->nNode = rTmp.nEnd;
122     rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), 0 );
123     return rPam;
124 }
125 
126 
127 
128 // Numerierung Outline Regelwerk
129 
130 
131 void SwEditShell::SetOutlineNumRule(const SwNumRule& rRule)
132 {
133     StartAllAction();       // Klammern fuers Updaten !!
134     GetDoc()->SetOutlineNumRule(rRule);
135     EndAllAction();
136 }
137 
138 
139 const SwNumRule* SwEditShell::GetOutlineNumRule() const
140 {
141     return GetDoc()->GetOutlineNumRule();
142 }
143 
144 // setzt, wenn noch keine Numerierung, sonst wird geaendert
145 // arbeitet mit alten und neuen Regeln, nur Differenzen aktualisieren
146 
147 // Absaetze ohne Numerierung, aber mit Einzuegen
148 
149 sal_Bool SwEditShell::NoNum()
150 {
151     sal_Bool bRet = sal_True;
152     StartAllAction();
153 
154     SwPaM* pCrsr = GetCrsr();
155     if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
156     {
157         GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
158         SwPamRanges aRangeArr( *pCrsr );
159         SwPaM aPam( *pCrsr->GetPoint() );
160         for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
161             bRet = bRet && GetDoc()->NoNum( aRangeArr.SetPam( n, aPam ));
162         GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
163     }
164     else
165         bRet = GetDoc()->NoNum( *pCrsr );
166 
167     EndAllAction();
168     return bRet;
169 }
170 // Loeschen, Splitten der Aufzaehlungsliste
171 
172 // -> #i29560#
173 sal_Bool SwEditShell::HasNumber() const
174 {
175     sal_Bool bResult = sal_False;
176 
177     const SwTxtNode * pTxtNd =
178         GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
179 
180     if (pTxtNd)
181     {
182         bResult = pTxtNd->HasNumber();
183 
184         // --> OD 2005-10-26 #b6340308#
185         // special case: outline numbered, not counted paragraph
186         if ( bResult &&
187              pTxtNd->GetNumRule() == GetDoc()->GetOutlineNumRule() &&
188              !pTxtNd->IsCountedInList() )
189         {
190             bResult = sal_False;
191         }
192         // <--
193     }
194 
195     return bResult;
196 }
197 
198 sal_Bool SwEditShell::HasBullet() const
199 {
200     sal_Bool bResult = sal_False;
201 
202     const SwTxtNode * pTxtNd =
203         GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
204 
205     if (pTxtNd)
206     {
207         bResult = pTxtNd->HasBullet();
208     }
209 
210     return bResult;
211 }
212 // <- #i29560#
213 
214 void SwEditShell::DelNumRules()
215 {
216     StartAllAction();
217 
218     SwPaM* pCrsr = GetCrsr();
219     if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
220     {
221         GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
222         SwPamRanges aRangeArr( *pCrsr );
223         SwPaM aPam( *pCrsr->GetPoint() );
224         for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
225         {
226             GetDoc()->DelNumRules( aRangeArr.SetPam( n, aPam ) );
227         }
228         GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
229     }
230     else
231         GetDoc()->DelNumRules( *pCrsr );
232 
233     // rufe das AttrChangeNotify auf der UI-Seite. Sollte eigentlich
234     // ueberfluessig sein, aber VB hatte darueber eine Bugrep.
235     CallChgLnk();
236 
237     // --> OD 2005-10-24 #126346# - cursor can not be anymore in
238     // front of a label, because numbering/bullet is deleted.
239     SetInFrontOfLabel( sal_False );
240     // <--
241 
242     GetDoc()->SetModified();
243     EndAllAction();
244 }
245 
246 // Hoch-/Runterstufen
247 
248 
249 sal_Bool SwEditShell::NumUpDown( sal_Bool bDown )
250 {
251     StartAllAction();
252 
253     sal_Bool bRet = sal_True;
254     SwPaM* pCrsr = GetCrsr();
255     if( pCrsr->GetNext() == pCrsr )         // keine Mehrfachselektion ?
256         bRet = GetDoc()->NumUpDown( *pCrsr, bDown );
257     else
258     {
259         GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
260         SwPamRanges aRangeArr( *pCrsr );
261         SwPaM aPam( *pCrsr->GetPoint() );
262         for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
263             bRet = bRet && GetDoc()->NumUpDown( aRangeArr.SetPam( n, aPam ), bDown );
264         GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
265     }
266     GetDoc()->SetModified();
267 
268     // --> FME 2005-09-19 #i54693# Update marked numbering levels
269     if ( IsInFrontOfLabel() )
270         UpdateMarkedListLevel();
271     // <--
272 
273     CallChgLnk();
274 
275     EndAllAction();
276     return bRet;
277 }
278 // -> #i23726#
279 sal_Bool SwEditShell::IsFirstOfNumRule() const
280 {
281     sal_Bool bResult = sal_False;
282 
283     SwPaM * pCrsr = GetCrsr();
284     if (pCrsr->GetNext() == pCrsr)
285     {
286         bResult = IsFirstOfNumRule(*pCrsr);
287     }
288 
289     return bResult;
290 }
291 
292 sal_Bool SwEditShell::IsFirstOfNumRule(const SwPaM & rPaM) const
293 {
294     sal_Bool bResult = sal_False;
295 
296     SwPosition aPos(*rPaM.GetPoint());
297     bResult = GetDoc()->IsFirstOfNumRule(aPos);
298 
299     return bResult;
300 }
301 // <- #i23726#
302 
303 // -> #i23725#
304 // --> OD 2008-06-09 #i90078#
305 // Remove unused default parameter <nLevel> and <bRelative>.
306 // Adjust method name and parameter name
307 void SwEditShell::ChangeIndentOfAllListLevels( short nDiff )
308 {
309     StartAllAction();
310 
311     const SwNumRule *pCurNumRule = GetCurNumRule();
312     //#120911# check if numbering rule really exists
313     if (pCurNumRule)
314     {
315         SwNumRule aRule(*pCurNumRule);
316         // --> OD 2008-06-09 #i90078#
317         aRule.ChangeIndent( nDiff );
318         // <--
319 
320         // --> OD 2008-03-17 #refactorlists#
321         // no start of new list
322         SetCurNumRule( aRule, false );
323         // <--
324     }
325 
326     EndAllAction();
327 }
328 
329 // --> OD 2008-06-09 #i90078#
330 // Adjust method name
331 void SwEditShell::SetIndent(short nIndent, const SwPosition & rPos)
332 // <--
333 {
334     StartAllAction();
335 
336     SwNumRule *pCurNumRule = GetDoc()->GetCurrNumRule(rPos);
337 
338     if (pCurNumRule)
339     {
340         SwPaM aPaM(rPos);
341         SwTxtNode * pTxtNode = aPaM.GetNode()->GetTxtNode();
342 
343         // --> OD 2008-06-09 #i90078#
344 //        int nLevel = -1;
345 //        int nReferenceLevel = pTxtNode->GetActualListLevel();
346 //        if (! IsFirstOfNumRule(aPaM))
347 //            nLevel = nReferenceLevel;
348 
349         SwNumRule aRule(*pCurNumRule);
350 //        aRule.ChangeIndent(nIndent, nLevel, nReferenceLevel, sal_False);
351         if ( IsFirstOfNumRule() )
352         {
353             aRule.SetIndentOfFirstListLevelAndChangeOthers( nIndent );
354         }
355         else if ( pTxtNode->GetActualListLevel() >= 0  )
356         {
357             aRule.SetIndent( nIndent,
358                              static_cast<sal_uInt16>(pTxtNode->GetActualListLevel()) );
359         }
360         // <--
361 
362         // --> OD 2005-02-18 #i42921# - 3rd parameter = false in order to
363         // suppress setting of num rule at <aPaM>.
364         // --> OD 2008-03-17 #refactorlists#
365         // do not apply any list
366         GetDoc()->SetNumRule( aPaM, aRule, false, String(), sal_False );
367         // <--
368     }
369 
370     EndAllAction();
371 }
372 // <- #i23725#
373 
374 sal_Bool SwEditShell::MoveParagraph( long nOffset )
375 {
376     StartAllAction();
377 
378     SwPaM *pCrsr = GetCrsr();
379     if( !pCrsr->HasMark() )
380     {
381         // sorge dafuer, das Bound1 und Bound2 im gleichen Node stehen
382         pCrsr->SetMark();
383         pCrsr->DeleteMark();
384     }
385 
386     sal_Bool bRet = GetDoc()->MoveParagraph( *pCrsr, nOffset );
387 
388     GetDoc()->SetModified();
389     EndAllAction();
390     return bRet;
391 }
392 
393 //#outline level add by zhaojianwei
394 int SwEditShell::GetCurrentParaOutlineLevel( ) const
395 {
396     int nLevel = 0;
397 
398     SwPaM* pCrsr = GetCrsr();
399     const SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode();
400     if( pTxtNd )
401         nLevel = pTxtNd->GetAttrOutlineLevel();
402     return nLevel;
403 }
404 //<-end,zhaojianwei
405 
406 void SwEditShell::GetCurrentOutlineLevels( sal_uInt8& rUpper, sal_uInt8& rLower )
407 {
408     SwPaM* pCrsr = GetCrsr();
409     SwPaM aCrsr( *pCrsr->Start() );
410     aCrsr.SetMark();
411     if( pCrsr->HasMark() )
412         *aCrsr.GetPoint() = *pCrsr->End();
413     GetDoc()->GotoNextNum( *aCrsr.GetPoint(), sal_False,
414                             &rUpper, &rLower );
415 }
416 
417 sal_Bool SwEditShell::MoveNumParas( sal_Bool bUpperLower, sal_Bool bUpperLeft )
418 {
419     StartAllAction();
420 
421     // auf alle Selektionen ??
422     SwPaM* pCrsr = GetCrsr();
423     SwPaM aCrsr( *pCrsr->Start() );
424     aCrsr.SetMark();
425 
426     if( pCrsr->HasMark() )
427         *aCrsr.GetPoint() = *pCrsr->End();
428 
429     sal_Bool bRet = sal_False;
430     sal_uInt8 nUpperLevel, nLowerLevel;
431     if( GetDoc()->GotoNextNum( *aCrsr.GetPoint(), sal_False,
432                                 &nUpperLevel, &nLowerLevel ))
433     {
434         if( bUpperLower )
435         {
436             // ueber die naechste Nummerierung
437             long nOffset = 0;
438             const SwNode* pNd;
439 
440             if( bUpperLeft )        // verschiebe nach oben
441             {
442                 SwPosition aPos( *aCrsr.GetMark() );
443                 if( GetDoc()->GotoPrevNum( aPos, sal_False ) )
444                     nOffset = aPos.nNode.GetIndex() -
445                             aCrsr.GetMark()->nNode.GetIndex();
446                 else
447                 {
448                     sal_uLong nStt = aPos.nNode.GetIndex(), nIdx = nStt - 1;
449                     while( nIdx && (
450                         ( pNd = GetDoc()->GetNodes()[ nIdx ])->IsSectionNode() ||
451                         ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode())))
452                         --nIdx;
453                     if( GetDoc()->GetNodes()[ nIdx ]->IsTxtNode() )
454                         nOffset = nIdx - nStt;
455                 }
456             }
457             else                    // verschiebe nach unten
458             {
459                 const SwNumRule* pOrig = aCrsr.GetNode(sal_False)->GetTxtNode()->GetNumRule();
460                 if( aCrsr.GetNode()->IsTxtNode() &&
461                     pOrig == aCrsr.GetNode()->GetTxtNode()->GetNumRule() )
462                 {
463                     sal_uLong nStt = aCrsr.GetPoint()->nNode.GetIndex(), nIdx = nStt+1;
464 
465                     while (nIdx < GetDoc()->GetNodes().Count()-1)
466                     {
467                         pNd = GetDoc()->GetNodes()[ nIdx ];
468 
469                         if (pNd->IsSectionNode() ||
470                             ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode()) ||
471                             ( pNd->IsTxtNode() && pOrig == ((SwTxtNode*)pNd)->GetNumRule() &&
472                               ((SwTxtNode*)pNd)->GetActualListLevel() > nUpperLevel ))
473                         {
474                             ++nIdx;
475                         }
476                         // --> OD 2005-11-14 #i57856#
477                         else
478                         {
479                             break;
480                         }
481                         // <--
482                     }
483 
484                     if( nStt == nIdx || !GetDoc()->GetNodes()[ nIdx ]->IsTxtNode() )
485                         nOffset = 1;
486                     else
487                         nOffset = nIdx - nStt;
488                 }
489                 else
490                     nOffset = 1;
491             }
492 
493             if( nOffset )
494             {
495                 aCrsr.Move( fnMoveBackward, fnGoNode );
496                 bRet = GetDoc()->MoveParagraph( aCrsr, nOffset );
497             }
498         }
499         else if( bUpperLeft ? nUpperLevel : nLowerLevel+1 < MAXLEVEL )
500         {
501             aCrsr.Move( fnMoveBackward, fnGoNode );
502             bRet = GetDoc()->NumUpDown( aCrsr, !bUpperLeft );
503         }
504     }
505 
506     GetDoc()->SetModified();
507     EndAllAction();
508     return bRet;
509 }
510 
511 sal_Bool SwEditShell::OutlineUpDown( short nOffset )
512 {
513     StartAllAction();
514 
515     sal_Bool bRet = sal_True;
516     SwPaM* pCrsr = GetCrsr();
517     if( pCrsr->GetNext() == pCrsr )         // keine Mehrfachselektion ?
518         bRet = GetDoc()->OutlineUpDown( *pCrsr, nOffset );
519     else
520     {
521         GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
522         SwPamRanges aRangeArr( *pCrsr );
523         SwPaM aPam( *pCrsr->GetPoint() );
524         for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
525             bRet = bRet && GetDoc()->OutlineUpDown(
526                                     aRangeArr.SetPam( n, aPam ), nOffset );
527         GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
528     }
529     GetDoc()->SetModified();
530     EndAllAction();
531     return bRet;
532 }
533 
534 
535 sal_Bool SwEditShell::MoveOutlinePara( short nOffset )
536 {
537     StartAllAction();
538     sal_Bool bRet = GetDoc()->MoveOutlinePara( *GetCrsr(), nOffset );
539     EndAllAction();
540     return bRet;
541 }
542 
543 // Outlines and SubOutline are ReadOnly?
544 sal_Bool SwEditShell::IsProtectedOutlinePara() const
545 {
546     sal_Bool bRet = sal_False;
547     const SwNode& rNd = GetCrsr()->Start()->nNode.GetNode();
548     if( rNd.IsTxtNode() )
549     {
550         const SwOutlineNodes& rOutlNd = GetDoc()->GetNodes().GetOutLineNds();
551         SwNodePtr pNd = (SwNodePtr)&rNd;
552         sal_Bool bFirst = sal_True;
553         sal_uInt16 nPos;
554         int nLvl(0);
555         if( !rOutlNd.Seek_Entry( pNd, &nPos ) && nPos )
556             --nPos;
557 
558         for( ; nPos < rOutlNd.Count(); ++nPos )
559         {
560             SwNodePtr pTmpNd = rOutlNd[ nPos ];
561 
562             // --> OD 2008-04-02 #refactorlists#
563 //            sal_uInt8 nTmpLvl = GetRealLevel( pTmpNd->GetTxtNode()->
564 //                                    GetTxtColl()->GetOutlineLevel() );
565  //           int nTmpLvl = pTmpNd->GetTxtNode()->GetOutlineLevel();//#outline level,zhaojianwei
566             int nTmpLvl = pTmpNd->GetTxtNode()->GetAttrOutlineLevel();
567  //           ASSERT( nTmpLvl >= 0 && nTmpLvl < MAXLEVEL,
568             ASSERT( nTmpLvl >= 0 && nTmpLvl <= MAXLEVEL,            //<-end,zhaojianwei
569                     "<SwEditShell::IsProtectedOutlinePara()>" );
570             // <--
571             if( bFirst )
572             {
573                 nLvl = nTmpLvl;
574                 bFirst = sal_False;
575             }
576             else if( nLvl >= nTmpLvl )
577                 break;
578 
579             if( pTmpNd->IsProtect() )
580             {
581                 bRet = sal_True;
582                 break;
583             }
584         }
585     }
586 #ifdef DBG_UTIL
587     else
588     {
589         ASSERT(!this, "Cursor not on an outline node" );
590     }
591 #endif
592     return bRet;
593 }
594 
595 /** Test whether outline may be moved (bCopy == false)
596  *                           or copied (bCopy == true)
597  * Verify these conditions:
598  * 1) outline must be within main body (and not in redline)
599  * 2) outline must not be within table
600  * 3) if bCopy is set, outline must not be write protected
601  */
602 sal_Bool lcl_IsOutlineMoveAndCopyable( const SwDoc* pDoc, sal_uInt16 nIdx, bool bCopy )
603 {
604     const SwNodes& rNds = pDoc->GetNodes();
605     const SwNode* pNd = rNds.GetOutLineNds()[ nIdx ];
606     return pNd->GetIndex() >= rNds.GetEndOfExtras().GetIndex() &&   // 1) body
607             !pNd->FindTableNode() &&                                // 2) table
608             ( bCopy || !pNd->IsProtect() );                         // 3) write
609 }
610 
611 sal_Bool SwEditShell::IsOutlineMovable( sal_uInt16 nIdx ) const
612 {
613     return lcl_IsOutlineMoveAndCopyable( GetDoc(), nIdx, false );
614 }
615 
616 sal_Bool SwEditShell::IsOutlineCopyable( sal_uInt16 nIdx ) const
617 {
618     return lcl_IsOutlineMoveAndCopyable( GetDoc(), nIdx, true );
619 }
620 
621 
622 sal_Bool SwEditShell::NumOrNoNum( sal_Bool bNumOn, sal_Bool bChkStart ) // #115901#
623 {
624     sal_Bool bRet = sal_False;
625     SwPaM* pCrsr = GetCrsr();
626     if( pCrsr->GetNext() == pCrsr && !pCrsr->HasMark() &&
627         ( !bChkStart || !pCrsr->GetPoint()->nContent.GetIndex()) )
628     {
629         StartAllAction();       // Klammern fuers Updaten !!
630         // #115901#
631         bRet = GetDoc()->NumOrNoNum( pCrsr->GetPoint()->nNode, !bNumOn ); // #i29560#
632         EndAllAction();
633     }
634     return bRet;
635 }
636 
637 sal_Bool SwEditShell::IsNoNum( sal_Bool bChkStart ) const
638 {
639     // ein Backspace im Absatz ohne Nummer wird zum Delete
640     sal_Bool bResult = sal_False;
641     SwPaM* pCrsr = GetCrsr();
642 
643     if (pCrsr->GetNext() == pCrsr && !pCrsr->HasMark() &&
644         (!bChkStart || !pCrsr->GetPoint()->nContent.GetIndex()))
645     {
646         const SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode();
647 
648         if (pTxtNd)
649         {
650             bResult =  ! pTxtNd->IsCountedInList();
651         }
652     }
653 
654     return bResult;
655 }
656 
657 // --> OD 2008-02-29 #refactorlists# - removed <pHasChilds>
658 sal_uInt8 SwEditShell::GetNumLevel() const
659 {
660     // gebe die akt. Ebene zurueck, auf der sich der Point vom Cursor befindet
661     //sal_uInt8 nLevel = NO_NUMBERING;  //#outline level,zhaojianwei
662     sal_uInt8 nLevel = MAXLEVEL;        //end,zhaojianwei
663 
664     SwPaM* pCrsr = GetCrsr();
665     const SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode();
666 
667     // --> FME 2005-09-12 #124972# Made code robust:
668     ASSERT( pTxtNd, "GetNumLevel() without text node" )
669     if ( !pTxtNd )
670         return nLevel;
671     // <--
672 
673     const SwNumRule* pRule = pTxtNd->GetNumRule();
674     if(pRule)
675     {
676         // --> OD 2008-05-09 #refactorlists#
677         const int nListLevelOfTxtNode( pTxtNd->GetActualListLevel() );
678         if ( nListLevelOfTxtNode >= 0 )
679         {
680             nLevel = static_cast<sal_uInt8>( nListLevelOfTxtNode );
681         }
682         // <--
683     }
684 
685     return nLevel;
686 }
687 
688 const SwNumRule* SwEditShell::GetCurNumRule() const
689 {
690     return GetDoc()->GetCurrNumRule( *GetCrsr()->GetPoint() );
691 }
692 
693 // OD 2008-02-08 #newlistlevelattrs# - add handling of parameter <bResetIndentAttrs>
694 // --> OD 2008-03-17 #refactorlists#
695 void SwEditShell::SetCurNumRule( const SwNumRule& rRule,
696                                  const bool bCreateNewList,
697                                  const String sContinuedListId,
698                                  const bool bResetIndentAttrs )
699 {
700     StartAllAction();
701 
702     GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
703 
704     SwPaM* pCrsr = GetCrsr();
705     if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
706     {
707         SwPamRanges aRangeArr( *pCrsr );
708         SwPaM aPam( *pCrsr->GetPoint() );
709         for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
710           {
711             aRangeArr.SetPam( n, aPam );
712             // --> OD 2008-02-08 #newlistlevelattrs#
713             // --> OD 2008-03-17 #refactorlists#
714             GetDoc()->SetNumRule( aPam, rRule,
715                                   bCreateNewList, sContinuedListId,
716                                   sal_True, bResetIndentAttrs );
717             // <--
718             GetDoc()->SetCounted( aPam, true );
719           }
720     }
721     else
722     {
723         // --> OD 2008-02-08 #newlistlevelattrs#
724         // --> OD 2008-03-17 #refactorlists#
725         GetDoc()->SetNumRule( *pCrsr, rRule,
726                               bCreateNewList, sContinuedListId,
727                               sal_True, bResetIndentAttrs );
728         GetDoc()->SetCounted( *pCrsr, true );
729     }
730     GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
731 
732     EndAllAction();
733 }
734 
735 String SwEditShell::GetUniqueNumRuleName( const String* pChkStr, sal_Bool bAutoNum ) const
736 {
737     return GetDoc()->GetUniqueNumRuleName( pChkStr, bAutoNum );
738 }
739 
740 void SwEditShell::ChgNumRuleFmts( const SwNumRule& rRule )
741 {
742     StartAllAction();
743     GetDoc()->ChgNumRuleFmts( rRule );
744     EndAllAction();
745 }
746 
747 sal_Bool SwEditShell::ReplaceNumRule( const String& rOldRule, const String& rNewRule )
748 {
749     StartAllAction();
750     sal_Bool bRet = GetDoc()->ReplaceNumRule( *GetCrsr()->GetPoint(), rOldRule, rNewRule );
751     EndAllAction();
752     return bRet;
753 }
754 
755 void SwEditShell::SetNumRuleStart( sal_Bool bFlag )
756 {
757     StartAllAction();
758 
759     SwPaM* pCrsr = GetCrsr();
760     if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
761     {
762         GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
763         SwPamRanges aRangeArr( *pCrsr );
764         SwPaM aPam( *pCrsr->GetPoint() );
765         for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
766             GetDoc()->SetNumRuleStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), bFlag );
767         GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
768     }
769     else
770         GetDoc()->SetNumRuleStart( *pCrsr->GetPoint(), bFlag );
771 
772     EndAllAction();
773 }
774 
775 sal_Bool SwEditShell::IsNumRuleStart() const
776 {
777     sal_Bool bResult = sal_False;
778     const SwTxtNode* pTxtNd = GetCrsr()->GetNode()->GetTxtNode();
779     if( pTxtNd )
780         bResult = pTxtNd->IsListRestart() ? sal_True : sal_False;
781     return bResult;
782 }
783 
784 void SwEditShell::SetNodeNumStart( sal_uInt16 nStt )
785 {
786     StartAllAction();
787 
788     SwPaM* pCrsr = GetCrsr();
789     if( pCrsr->GetNext() != pCrsr )         // Mehrfachselektion ?
790     {
791         GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
792         SwPamRanges aRangeArr( *pCrsr );
793         SwPaM aPam( *pCrsr->GetPoint() );
794         for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
795             GetDoc()->SetNodeNumStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), nStt );
796         GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
797     }
798     else
799         GetDoc()->SetNodeNumStart( *pCrsr->GetPoint(), nStt );
800 
801     EndAllAction();
802 }
803 
804 sal_uInt16 SwEditShell::GetNodeNumStart() const
805 {
806     const SwTxtNode* pTxtNd = GetCrsr()->GetNode()->GetTxtNode();
807     // --> OD 2008-02-28 #refactorlists#
808     // correction: check, if list restart value is set at text node and
809     // use new method <SwTxtNode::GetAttrListRestartValue()>.
810     // return USHRT_MAX, if no list restart value is found.
811     if ( pTxtNd && pTxtNd->HasAttrListRestartValue() )
812     {
813         return static_cast<sal_uInt16>(pTxtNd->GetAttrListRestartValue());
814     }
815     return USHRT_MAX;
816     // <--
817 }
818 
819 /*-- 26.08.2005 14:47:17---------------------------------------------------
820 
821   -----------------------------------------------------------------------*/
822 // --> OD 2008-03-18 #refactorlists#
823 const SwNumRule * SwEditShell::SearchNumRule( const bool bForward,
824                                               const bool bNum,
825                                               const bool bOutline,
826                                               int nNonEmptyAllowed,
827                                               String& sListId )
828 {
829     return GetDoc()->SearchNumRule( *(bForward ? GetCrsr()->End() : GetCrsr()->Start()),
830                                     bForward, bNum, bOutline, nNonEmptyAllowed,
831                                     sListId );
832 }
833 // <--
834