xref: /AOO41X/main/sw/source/core/edit/ednumber.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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