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