Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <hintids.hxx>
21 : #include <editsh.hxx>
22 : #include <edimp.hxx>
23 : #include <doc.hxx>
24 : #include <IDocumentUndoRedo.hxx>
25 : #include <IDocumentState.hxx>
26 : #include <ndtxt.hxx>
27 : #include <paratr.hxx>
28 : #include <swundo.hxx>
29 : #include <numrule.hxx>
30 :
31 1362 : SwPamRanges::SwPamRanges( const SwPaM& rRing )
32 : {
33 1362 : const SwPaM* pTmp = &rRing;
34 1398 : do {
35 1398 : Insert( pTmp->GetMark()->nNode, pTmp->GetPoint()->nNode );
36 1398 : } while( &rRing != ( pTmp = (const SwPaM*)pTmp->GetNext() ));
37 1362 : }
38 :
39 1398 : void SwPamRanges::Insert( const SwNodeIndex& rIdx1, const SwNodeIndex& rIdx2 )
40 : {
41 1398 : SwPamRange aRg( rIdx1.GetIndex(), rIdx2.GetIndex() );
42 1398 : if( aRg.nEnd < aRg.nStart )
43 0 : { aRg.nStart = aRg.nEnd; aRg.nEnd = rIdx1.GetIndex(); }
44 :
45 1398 : _SwPamRanges::const_iterator it = lower_bound(aRg); //search Insert Position
46 1398 : sal_uInt16 nPos = it - begin();
47 1398 : if (!empty() && (it != end()) && (*it) == aRg)
48 : {
49 : // is the one in the Array smaller?
50 0 : SwPamRange const& rTmp = _SwPamRanges::operator[](nPos);
51 0 : if( rTmp.nEnd < aRg.nEnd )
52 : {
53 0 : aRg.nEnd = rTmp.nEnd;
54 0 : erase(begin() + nPos); // combine
55 : }
56 : else
57 0 : return; // done, because by precondition everything is combined
58 : }
59 :
60 : bool bEnd;
61 1398 : do {
62 1398 : bEnd = true;
63 :
64 : // combine with predecessor?
65 1398 : if( nPos > 0 )
66 : {
67 36 : SwPamRange const& rTmp = _SwPamRanges::operator[](nPos-1);
68 36 : if( rTmp.nEnd == aRg.nStart
69 36 : || rTmp.nEnd+1 == aRg.nStart )
70 : {
71 0 : aRg.nStart = rTmp.nStart;
72 0 : bEnd = false;
73 0 : erase( begin() + --nPos ); // combine
74 : }
75 : // range contained in rTmp?
76 36 : else if( rTmp.nStart <= aRg.nStart && aRg.nEnd <= rTmp.nEnd )
77 0 : return;
78 : }
79 : // combine with successor?
80 1398 : if( nPos < size() )
81 : {
82 0 : SwPamRange const& rTmp = _SwPamRanges::operator[](nPos);
83 0 : if( rTmp.nStart == aRg.nEnd ||
84 0 : rTmp.nStart == aRg.nEnd+1 )
85 : {
86 0 : aRg.nEnd = rTmp.nEnd;
87 0 : bEnd = false;
88 0 : erase( begin() + nPos ); // combine
89 : }
90 :
91 : // range contained in rTmp?
92 0 : else if( rTmp.nStart <= aRg.nStart && aRg.nEnd <= rTmp.nEnd )
93 0 : return;
94 : }
95 1398 : } while( !bEnd );
96 :
97 1398 : _SwPamRanges::insert( aRg );
98 : }
99 :
100 1398 : SwPaM& SwPamRanges::SetPam( sal_uInt16 nArrPos, SwPaM& rPam )
101 : {
102 : OSL_ASSERT( nArrPos < Count() );
103 1398 : const SwPamRange& rTmp = (*this)[ nArrPos ];
104 1398 : rPam.GetPoint()->nNode = rTmp.nStart;
105 1398 : rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), 0 );
106 1398 : rPam.SetMark();
107 1398 : rPam.GetPoint()->nNode = rTmp.nEnd;
108 1398 : rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), 0 );
109 1398 : return rPam;
110 : }
111 :
112 : // Rule book for outline numbering
113 :
114 0 : void SwEditShell::SetOutlineNumRule(const SwNumRule& rRule)
115 : {
116 0 : StartAllAction(); // bracketing for updating!
117 0 : GetDoc()->SetOutlineNumRule(rRule);
118 0 : EndAllAction();
119 0 : }
120 :
121 0 : const SwNumRule* SwEditShell::GetOutlineNumRule() const
122 : {
123 0 : return GetDoc()->GetOutlineNumRule();
124 : }
125 :
126 : // Set if there is no numbering yet, else update.
127 : // Works with old and new rules. Update only differences.
128 :
129 : // paragraphs without numbering, with indentations
130 0 : bool SwEditShell::NoNum()
131 : {
132 0 : bool bRet = true;
133 0 : StartAllAction();
134 :
135 0 : SwPaM* pCrsr = GetCrsr();
136 0 : if( pCrsr->GetNext() != pCrsr ) // Multiple selection?
137 : {
138 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
139 0 : SwPamRanges aRangeArr( *pCrsr );
140 0 : SwPaM aPam( *pCrsr->GetPoint() );
141 0 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
142 0 : bRet = bRet && GetDoc()->NoNum( aRangeArr.SetPam( n, aPam ));
143 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
144 : }
145 : else
146 0 : bRet = GetDoc()->NoNum( *pCrsr );
147 :
148 0 : EndAllAction();
149 0 : return bRet;
150 : }
151 :
152 910 : bool SwEditShell::SelectionHasNumber() const
153 : {
154 910 : bool bResult = HasNumber();
155 : const SwTxtNode * pTxtNd =
156 910 : GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
157 910 : if (!bResult && pTxtNd && pTxtNd->Len()==0 && !pTxtNd->GetNumRule()) {
158 681 : SwPamRanges aRangeArr( *GetCrsr() );
159 1362 : SwPaM aPam( *GetCrsr()->GetPoint() );
160 1380 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
161 : {
162 699 : aRangeArr.SetPam( n, aPam );
163 : {
164 699 : sal_uInt32 nStt = aPam.GetPoint()->nNode.GetIndex(),
165 699 : nEnd = aPam.GetMark()->nNode.GetIndex();
166 699 : if( nStt > nEnd )
167 : {
168 0 : sal_uInt32 nTmp = nStt; nStt = nEnd; nEnd = nTmp;
169 : }
170 1398 : for (sal_uInt32 nPos = nStt; nPos<=nEnd; nPos++)
171 : {
172 699 : pTxtNd = mpDoc->GetNodes()[nPos]->GetTxtNode();
173 699 : if (pTxtNd && pTxtNd->Len()!=0)
174 : {
175 0 : bResult = pTxtNd->HasNumber();
176 :
177 : // #b6340308# special case: outline numbered, not counted paragraph
178 0 : if ( bResult &&
179 0 : pTxtNd->GetNumRule() == GetDoc()->GetOutlineNumRule() &&
180 0 : !pTxtNd->IsCountedInList() )
181 : {
182 0 : bResult = false;
183 : }
184 0 : if (bResult==false) {
185 0 : break;
186 : }
187 : }
188 : }
189 : }
190 681 : }
191 :
192 : }
193 :
194 910 : return bResult;
195 : }
196 :
197 : // add a new function to determine number on/off status
198 910 : bool SwEditShell::SelectionHasBullet() const
199 : {
200 910 : bool bResult = HasBullet();
201 : const SwTxtNode * pTxtNd =
202 910 : GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
203 910 : if (!bResult && pTxtNd && pTxtNd->Len()==0 && !pTxtNd->GetNumRule()) {
204 681 : SwPamRanges aRangeArr( *GetCrsr() );
205 1362 : SwPaM aPam( *GetCrsr()->GetPoint() );
206 1380 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
207 : {
208 699 : aRangeArr.SetPam( n, aPam );
209 : {
210 699 : sal_uInt32 nStt = aPam.GetPoint()->nNode.GetIndex(),
211 699 : nEnd = aPam.GetMark()->nNode.GetIndex();
212 699 : if( nStt > nEnd )
213 : {
214 0 : sal_uInt32 nTmp = nStt; nStt = nEnd; nEnd = nTmp;
215 : }
216 1398 : for (sal_uInt32 nPos = nStt; nPos<=nEnd; nPos++)
217 : {
218 699 : pTxtNd = mpDoc->GetNodes()[nPos]->GetTxtNode();
219 699 : if (pTxtNd && pTxtNd->Len()!=0)
220 : {
221 0 : bResult = pTxtNd->HasBullet();
222 :
223 0 : if (bResult==false) {
224 0 : break;
225 : }
226 : }
227 : }
228 : }
229 681 : }
230 : }
231 :
232 910 : return bResult;
233 : }
234 :
235 : // -> #i29560#
236 910 : bool SwEditShell::HasNumber() const
237 : {
238 910 : bool bResult = false;
239 :
240 : const SwTxtNode * pTxtNd =
241 910 : GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
242 :
243 910 : if (pTxtNd)
244 : {
245 910 : bResult = pTxtNd->HasNumber();
246 :
247 : // special case: outline numbered, not counted paragraph
248 910 : if ( bResult &&
249 910 : pTxtNd->GetNumRule() == GetDoc()->GetOutlineNumRule() &&
250 0 : !pTxtNd->IsCountedInList() )
251 : {
252 0 : bResult = false;
253 : }
254 : }
255 :
256 910 : return bResult;
257 : }
258 :
259 910 : bool SwEditShell::HasBullet() const
260 : {
261 910 : bool bResult = false;
262 :
263 : const SwTxtNode * pTxtNd =
264 910 : GetCrsr()->GetPoint()->nNode.GetNode().GetTxtNode();
265 :
266 910 : if (pTxtNd)
267 : {
268 910 : bResult = pTxtNd->HasBullet();
269 : }
270 :
271 910 : return bResult;
272 : }
273 : // <- #i29560#
274 :
275 : // delete, split list
276 0 : void SwEditShell::DelNumRules()
277 : {
278 0 : StartAllAction();
279 :
280 0 : SwPaM* pCrsr = GetCrsr();
281 0 : if( pCrsr->GetNext() != pCrsr ) // multi-selection?
282 : {
283 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
284 0 : SwPamRanges aRangeArr( *pCrsr );
285 0 : SwPaM aPam( *pCrsr->GetPoint() );
286 0 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
287 : {
288 0 : GetDoc()->DelNumRules( aRangeArr.SetPam( n, aPam ) );
289 : }
290 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
291 : }
292 : else
293 0 : GetDoc()->DelNumRules( *pCrsr );
294 :
295 : // Call AttrChangeNotify on the UI-side. Should actually be redundant but there was a bug once.
296 0 : CallChgLnk();
297 :
298 : // Cursor cannot be in front of a label anymore, because numbering/bullet is deleted.
299 0 : SetInFrontOfLabel( false );
300 :
301 0 : GetDoc()->getIDocumentState().SetModified();
302 0 : EndAllAction();
303 0 : }
304 :
305 : // up- & downgrading
306 0 : bool SwEditShell::NumUpDown( bool bDown )
307 : {
308 0 : StartAllAction();
309 :
310 0 : bool bRet = true;
311 0 : SwPaM* pCrsr = GetCrsr();
312 0 : if( pCrsr->GetNext() == pCrsr ) // no multiple selection ?
313 0 : bRet = GetDoc()->NumUpDown( *pCrsr, bDown );
314 : else
315 : {
316 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
317 0 : SwPamRanges aRangeArr( *pCrsr );
318 0 : SwPaM aPam( *pCrsr->GetPoint() );
319 0 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
320 0 : bRet = bRet && GetDoc()->NumUpDown( aRangeArr.SetPam( n, aPam ), bDown );
321 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
322 : }
323 0 : GetDoc()->getIDocumentState().SetModified();
324 :
325 : // #i54693# Update marked numbering levels
326 0 : if ( IsInFrontOfLabel() )
327 0 : UpdateMarkedListLevel();
328 :
329 0 : CallChgLnk();
330 :
331 0 : EndAllAction();
332 0 : return bRet;
333 : }
334 :
335 0 : bool SwEditShell::IsFirstOfNumRuleAtCrsrPos() const
336 : {
337 0 : return GetDoc()->IsFirstOfNumRuleAtPos( *GetCrsr()->GetPoint() );
338 : }
339 :
340 : // -> #i23725#, #i90078#
341 0 : void SwEditShell::ChangeIndentOfAllListLevels( const short nDiff )
342 : {
343 0 : StartAllAction();
344 :
345 0 : const SwNumRule *pCurNumRule = GetNumRuleAtCurrCrsrPos();
346 0 : if ( pCurNumRule != NULL )
347 : {
348 0 : SwNumRule aRule(*pCurNumRule);
349 0 : const SwNumFmt& aRootNumFmt(aRule.Get(0));
350 0 : if( nDiff > 0 || aRootNumFmt.GetIndentAt() + nDiff > 0) // fdo#42708
351 : {
352 : // #i90078#
353 0 : aRule.ChangeIndent( nDiff );
354 : }
355 : // no start of new list
356 0 : SetCurNumRule( aRule, false );
357 : }
358 :
359 0 : EndAllAction();
360 0 : }
361 :
362 : // #i90078#
363 0 : void SwEditShell::SetIndent(short nIndent, const SwPosition & rPos)
364 : {
365 0 : StartAllAction();
366 :
367 0 : SwNumRule *pCurNumRule = GetDoc()->GetNumRuleAtPos(rPos);
368 :
369 0 : if (pCurNumRule)
370 : {
371 0 : SwNumRule aRule(*pCurNumRule);
372 0 : if ( !IsMultiSelection() && IsFirstOfNumRuleAtCrsrPos() )
373 : {
374 0 : aRule.SetIndentOfFirstListLevelAndChangeOthers( nIndent );
375 : }
376 : else
377 : {
378 0 : const SwTxtNode* pTxtNode = rPos.nNode.GetNode().GetTxtNode();
379 0 : if ( pTxtNode != NULL
380 0 : && pTxtNode->GetActualListLevel() >= 0 )
381 : {
382 0 : aRule.SetIndent( nIndent, static_cast< sal_uInt16 >( pTxtNode->GetActualListLevel() ) );
383 : }
384 : }
385 :
386 : // change numbering rule - changed numbering rule is not applied at <aPaM>
387 0 : SwPaM aPaM(rPos);
388 0 : GetDoc()->SetNumRule( aPaM, aRule, false, OUString(), false );
389 : }
390 :
391 0 : EndAllAction();
392 0 : }
393 :
394 0 : bool SwEditShell::MoveParagraph( long nOffset )
395 : {
396 0 : StartAllAction();
397 :
398 0 : SwPaM *pCrsr = GetCrsr();
399 0 : if( !pCrsr->HasMark() )
400 : {
401 : // Ensures that Bound1 and Bound2 are in the same Node
402 0 : pCrsr->SetMark();
403 0 : pCrsr->DeleteMark();
404 : }
405 :
406 0 : bool bRet = GetDoc()->MoveParagraph( *pCrsr, nOffset );
407 :
408 0 : GetDoc()->getIDocumentState().SetModified();
409 0 : EndAllAction();
410 0 : return bRet;
411 : }
412 :
413 1051 : int SwEditShell::GetCurrentParaOutlineLevel( ) const
414 : {
415 1051 : int nLevel = 0;
416 :
417 1051 : SwPaM* pCrsr = GetCrsr();
418 1051 : const SwTxtNode* pTxtNd = pCrsr->GetNode().GetTxtNode();
419 1051 : if( pTxtNd )
420 1051 : nLevel = pTxtNd->GetAttrOutlineLevel();
421 1051 : return nLevel;
422 : }
423 :
424 0 : void SwEditShell::GetCurrentOutlineLevels( sal_uInt8& rUpper, sal_uInt8& rLower )
425 : {
426 0 : SwPaM* pCrsr = GetCrsr();
427 0 : SwPaM aCrsr( *pCrsr->Start() );
428 0 : aCrsr.SetMark();
429 0 : if( pCrsr->HasMark() )
430 0 : *aCrsr.GetPoint() = *pCrsr->End();
431 0 : GetDoc()->GotoNextNum( *aCrsr.GetPoint(), false, &rUpper, &rLower );
432 0 : }
433 :
434 0 : bool SwEditShell::MoveNumParas( bool bUpperLower, bool bUpperLeft )
435 : {
436 0 : StartAllAction();
437 :
438 : // On all selections?
439 0 : SwPaM* pCrsr = GetCrsr();
440 0 : SwPaM aCrsr( *pCrsr->Start() );
441 0 : aCrsr.SetMark();
442 :
443 0 : if( pCrsr->HasMark() )
444 0 : *aCrsr.GetPoint() = *pCrsr->End();
445 :
446 0 : bool bRet = false;
447 : sal_uInt8 nUpperLevel, nLowerLevel;
448 0 : if( GetDoc()->GotoNextNum( *aCrsr.GetPoint(), false,
449 0 : &nUpperLevel, &nLowerLevel ))
450 : {
451 0 : if( bUpperLower )
452 : {
453 : // on top of the next numbering
454 0 : long nOffset = 0;
455 : const SwNode* pNd;
456 :
457 0 : if( bUpperLeft ) // move up
458 : {
459 0 : SwPosition aPos( *aCrsr.GetMark() );
460 0 : if( GetDoc()->GotoPrevNum( aPos, false ) )
461 0 : nOffset = aPos.nNode.GetIndex() -
462 0 : aCrsr.GetMark()->nNode.GetIndex();
463 : else
464 : {
465 0 : sal_uLong nStt = aPos.nNode.GetIndex(), nIdx = nStt - 1;
466 0 : while( nIdx && (
467 0 : ( pNd = GetDoc()->GetNodes()[ nIdx ])->IsSectionNode() ||
468 0 : ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode())))
469 0 : --nIdx;
470 0 : if( GetDoc()->GetNodes()[ nIdx ]->IsTxtNode() )
471 0 : nOffset = nIdx - nStt;
472 0 : }
473 : }
474 : else // move down
475 : {
476 0 : const SwNumRule* pOrig = aCrsr.GetNode(false).GetTxtNode()->GetNumRule();
477 0 : if( aCrsr.GetNode().IsTxtNode() &&
478 0 : pOrig == aCrsr.GetNode().GetTxtNode()->GetNumRule() )
479 : {
480 0 : sal_uLong nStt = aCrsr.GetPoint()->nNode.GetIndex(), nIdx = nStt+1;
481 :
482 0 : while (nIdx < GetDoc()->GetNodes().Count()-1)
483 : {
484 0 : pNd = GetDoc()->GetNodes()[ nIdx ];
485 :
486 0 : if (pNd->IsSectionNode() ||
487 0 : ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode()) ||
488 0 : ( pNd->IsTxtNode() && pOrig == ((SwTxtNode*)pNd)->GetNumRule() &&
489 0 : ((SwTxtNode*)pNd)->GetActualListLevel() > nUpperLevel ))
490 : {
491 0 : ++nIdx;
492 : }
493 : // #i57856#
494 : else
495 : {
496 0 : break;
497 : }
498 : }
499 :
500 0 : if( nStt == nIdx || !GetDoc()->GetNodes()[ nIdx ]->IsTxtNode() )
501 0 : nOffset = 1;
502 : else
503 0 : nOffset = nIdx - nStt;
504 : }
505 : else
506 0 : nOffset = 1;
507 : }
508 :
509 0 : if( nOffset )
510 : {
511 0 : aCrsr.Move( fnMoveBackward, fnGoNode );
512 0 : bRet = GetDoc()->MoveParagraph( aCrsr, nOffset );
513 : }
514 : }
515 0 : else if( bUpperLeft ? nUpperLevel : nLowerLevel+1 < MAXLEVEL )
516 : {
517 0 : aCrsr.Move( fnMoveBackward, fnGoNode );
518 0 : bRet = GetDoc()->NumUpDown( aCrsr, !bUpperLeft );
519 : }
520 : }
521 :
522 0 : GetDoc()->getIDocumentState().SetModified();
523 0 : EndAllAction();
524 0 : return bRet;
525 : }
526 :
527 0 : bool SwEditShell::OutlineUpDown( short nOffset )
528 : {
529 0 : StartAllAction();
530 :
531 0 : bool bRet = true;
532 0 : SwPaM* pCrsr = GetCrsr();
533 0 : if( pCrsr->GetNext() == pCrsr ) // no multi selection?
534 0 : bRet = GetDoc()->OutlineUpDown( *pCrsr, nOffset );
535 : else
536 : {
537 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
538 0 : SwPamRanges aRangeArr( *pCrsr );
539 0 : SwPaM aPam( *pCrsr->GetPoint() );
540 0 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
541 0 : bRet = bRet && GetDoc()->OutlineUpDown(
542 0 : aRangeArr.SetPam( n, aPam ), nOffset );
543 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
544 : }
545 0 : GetDoc()->getIDocumentState().SetModified();
546 0 : EndAllAction();
547 0 : return bRet;
548 : }
549 :
550 0 : bool SwEditShell::MoveOutlinePara( short nOffset )
551 : {
552 0 : StartAllAction();
553 0 : bool bRet = GetDoc()->MoveOutlinePara( *GetCrsr(), nOffset );
554 0 : EndAllAction();
555 0 : return bRet;
556 : }
557 :
558 : // Outlines and SubOutline are ReadOnly?
559 0 : bool SwEditShell::IsProtectedOutlinePara() const
560 : {
561 0 : bool bRet = false;
562 0 : const SwNode& rNd = GetCrsr()->Start()->nNode.GetNode();
563 0 : if( rNd.IsTxtNode() )
564 : {
565 0 : const SwOutlineNodes& rOutlNd = GetDoc()->GetNodes().GetOutLineNds();
566 0 : SwNodePtr pNd = (SwNodePtr)&rNd;
567 0 : bool bFirst = true;
568 : sal_uInt16 nPos;
569 0 : int nLvl(0);
570 0 : if( !rOutlNd.Seek_Entry( pNd, &nPos ) && nPos )
571 0 : --nPos;
572 :
573 0 : for( ; nPos < rOutlNd.size(); ++nPos )
574 : {
575 0 : SwNodePtr pTmpNd = rOutlNd[ nPos ];
576 :
577 0 : int nTmpLvl = pTmpNd->GetTxtNode()->GetAttrOutlineLevel();
578 :
579 : OSL_ENSURE( nTmpLvl >= 0 && nTmpLvl <= MAXLEVEL,
580 : "<SwEditShell::IsProtectedOutlinePara()>" );
581 :
582 0 : if( bFirst )
583 : {
584 0 : nLvl = nTmpLvl;
585 0 : bFirst = false;
586 : }
587 0 : else if( nLvl >= nTmpLvl )
588 0 : break;
589 :
590 0 : if( pTmpNd->IsProtect() )
591 : {
592 0 : bRet = true;
593 0 : break;
594 : }
595 : }
596 : }
597 : #if OSL_DEBUG_LEVEL > 0
598 : else
599 : {
600 : OSL_FAIL("Cursor not on an outline node");
601 : }
602 : #endif
603 0 : return bRet;
604 : }
605 :
606 : /** Test whether outline may be moved (bCopy == false)
607 : * or copied (bCopy == true)
608 : * Verify these conditions:
609 : * 1) outline must be within main body (and not in redline)
610 : * 2) outline must not be within table
611 : * 3) if bCopy is set, outline must not be write protected
612 : */
613 0 : static bool lcl_IsOutlineMoveAndCopyable( const SwDoc* pDoc, sal_uInt16 nIdx, bool bCopy )
614 : {
615 0 : const SwNodes& rNds = pDoc->GetNodes();
616 0 : const SwNode* pNd = rNds.GetOutLineNds()[ nIdx ];
617 0 : return pNd->GetIndex() >= rNds.GetEndOfExtras().GetIndex() && // 1) body
618 0 : !pNd->FindTableNode() && // 2) table
619 0 : ( bCopy || !pNd->IsProtect() ); // 3) write
620 : }
621 :
622 0 : bool SwEditShell::IsOutlineMovable( sal_uInt16 nIdx ) const
623 : {
624 0 : return lcl_IsOutlineMoveAndCopyable( GetDoc(), nIdx, false );
625 : }
626 :
627 0 : bool SwEditShell::IsOutlineCopyable( sal_uInt16 nIdx ) const
628 : {
629 0 : return lcl_IsOutlineMoveAndCopyable( GetDoc(), nIdx, true );
630 : }
631 :
632 0 : bool SwEditShell::NumOrNoNum(
633 : bool bNumOn,
634 : bool bChkStart )
635 : {
636 0 : bool bRet = false;
637 :
638 0 : if ( !IsMultiSelection()
639 0 : && !HasSelection()
640 0 : && ( !bChkStart || IsSttPara() ) )
641 : {
642 0 : StartAllAction();
643 0 : bRet = GetDoc()->NumOrNoNum( GetCrsr()->GetPoint()->nNode, !bNumOn );
644 0 : EndAllAction();
645 : }
646 0 : return bRet;
647 : }
648 :
649 0 : bool SwEditShell::IsNoNum( bool bChkStart ) const
650 : {
651 : // a Backspace in the paragraph without number becomes a Delete
652 0 : bool bResult = false;
653 :
654 0 : if ( !IsMultiSelection()
655 0 : && !HasSelection()
656 0 : && ( !bChkStart || IsSttPara() ) )
657 : {
658 0 : const SwTxtNode* pTxtNd = GetCrsr()->GetNode().GetTxtNode();
659 0 : if ( pTxtNd != NULL )
660 : {
661 0 : bResult = !pTxtNd->IsCountedInList();
662 : }
663 : }
664 :
665 0 : return bResult;
666 : }
667 :
668 0 : sal_uInt8 SwEditShell::GetNumLevel() const
669 : {
670 : // return current level where the point of the cursor is
671 0 : sal_uInt8 nLevel = MAXLEVEL;
672 :
673 0 : SwPaM* pCrsr = GetCrsr();
674 0 : const SwTxtNode* pTxtNd = pCrsr->GetNode().GetTxtNode();
675 :
676 : OSL_ENSURE( pTxtNd, "GetNumLevel() without text node" );
677 0 : if ( pTxtNd == NULL )
678 0 : return nLevel;
679 :
680 0 : const SwNumRule* pRule = pTxtNd->GetNumRule();
681 0 : if ( pRule != NULL )
682 : {
683 0 : const int nListLevelOfTxtNode( pTxtNd->GetActualListLevel() );
684 0 : if ( nListLevelOfTxtNode >= 0 )
685 : {
686 0 : nLevel = static_cast<sal_uInt8>( nListLevelOfTxtNode );
687 : }
688 : }
689 :
690 0 : return nLevel;
691 : }
692 :
693 36999 : const SwNumRule* SwEditShell::GetNumRuleAtCurrCrsrPos() const
694 : {
695 36999 : return GetDoc()->GetNumRuleAtPos( *GetCrsr()->GetPoint() );
696 : }
697 :
698 0 : const SwNumRule* SwEditShell::GetNumRuleAtCurrentSelection() const
699 : {
700 0 : const SwNumRule* pNumRuleAtCurrentSelection = NULL;
701 :
702 0 : const SwPaM* pCurrentCrsr = GetCrsr();
703 0 : bool bDifferentNumRuleFound = false;
704 0 : const SwPaM* pCrsr = pCurrentCrsr;
705 0 : do
706 : {
707 0 : const SwNodeIndex aEndNode = pCrsr->End()->nNode;
708 :
709 0 : for ( SwNodeIndex aNode = pCrsr->Start()->nNode; aNode <= aEndNode; aNode++ )
710 : {
711 0 : const SwNumRule* pNumRule = GetDoc()->GetNumRuleAtPos( SwPosition( aNode ) );
712 0 : if ( pNumRule == NULL )
713 : {
714 0 : continue;
715 : }
716 0 : else if ( pNumRule != pNumRuleAtCurrentSelection )
717 : {
718 0 : if ( pNumRuleAtCurrentSelection == NULL )
719 : {
720 0 : pNumRuleAtCurrentSelection = pNumRule;
721 : }
722 : else
723 : {
724 0 : pNumRuleAtCurrentSelection = NULL;
725 0 : bDifferentNumRuleFound = true;
726 0 : break;
727 : }
728 : }
729 0 : }
730 :
731 0 : pCrsr = static_cast< const SwPaM* >(pCrsr->GetNext());
732 0 : } while ( !bDifferentNumRuleFound && pCrsr != pCurrentCrsr );
733 :
734 0 : return pNumRuleAtCurrentSelection;
735 : }
736 :
737 0 : void SwEditShell::SetCurNumRule( const SwNumRule& rRule,
738 : const bool bCreateNewList,
739 : const OUString& sContinuedListId,
740 : const bool bResetIndentAttrs )
741 : {
742 0 : StartAllAction();
743 :
744 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
745 :
746 0 : SwPaM* pCrsr = GetCrsr();
747 0 : if( IsMultiSelection() )
748 : {
749 0 : SwPamRanges aRangeArr( *pCrsr );
750 0 : SwPaM aPam( *pCrsr->GetPoint() );
751 0 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
752 : {
753 0 : aRangeArr.SetPam( n, aPam );
754 : GetDoc()->SetNumRule( aPam, rRule,
755 : bCreateNewList, sContinuedListId,
756 0 : true, bResetIndentAttrs );
757 0 : GetDoc()->SetCounted( aPam, true );
758 0 : }
759 : }
760 : else
761 : {
762 : GetDoc()->SetNumRule( *pCrsr, rRule,
763 : bCreateNewList, sContinuedListId,
764 0 : true, bResetIndentAttrs );
765 0 : GetDoc()->SetCounted( *pCrsr, true );
766 : }
767 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
768 :
769 0 : EndAllAction();
770 0 : }
771 :
772 0 : OUString SwEditShell::GetUniqueNumRuleName( const OUString* pChkStr, bool bAutoNum ) const
773 : {
774 0 : return GetDoc()->GetUniqueNumRuleName( pChkStr, bAutoNum );
775 : }
776 :
777 0 : void SwEditShell::ChgNumRuleFmts( const SwNumRule& rRule )
778 : {
779 0 : StartAllAction();
780 0 : GetDoc()->ChgNumRuleFmts( rRule );
781 0 : EndAllAction();
782 0 : }
783 :
784 0 : bool SwEditShell::ReplaceNumRule( const OUString& rOldRule, const OUString& rNewRule )
785 : {
786 0 : StartAllAction();
787 0 : bool bRet = GetDoc()->ReplaceNumRule( *GetCrsr()->GetPoint(), rOldRule, rNewRule );
788 0 : EndAllAction();
789 0 : return bRet;
790 : }
791 :
792 0 : void SwEditShell::SetNumRuleStart( bool bFlag, SwPaM* pPaM )
793 : {
794 0 : StartAllAction();
795 0 : SwPaM* pCrsr = pPaM ? pPaM : GetCrsr();
796 0 : if( pCrsr->GetNext() != pCrsr ) // multiple selection ?
797 : {
798 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
799 0 : SwPamRanges aRangeArr( *pCrsr );
800 0 : SwPaM aPam( *pCrsr->GetPoint() );
801 0 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
802 0 : GetDoc()->SetNumRuleStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), bFlag );
803 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
804 : }
805 : else
806 0 : GetDoc()->SetNumRuleStart( *pCrsr->GetPoint(), bFlag );
807 :
808 0 : EndAllAction();
809 0 : }
810 :
811 0 : bool SwEditShell::IsNumRuleStart( SwPaM* pPaM ) const
812 : {
813 0 : bool bResult = false;
814 0 : SwPaM* pCrsr = pPaM ? pPaM : GetCrsr( );
815 0 : const SwTxtNode* pTxtNd = pCrsr->GetNode().GetTxtNode();
816 0 : if( pTxtNd )
817 0 : bResult = pTxtNd->IsListRestart() ? sal_True : sal_False;
818 0 : return bResult;
819 : }
820 :
821 0 : void SwEditShell::SetNodeNumStart( sal_uInt16 nStt, SwPaM* pPaM )
822 : {
823 0 : StartAllAction();
824 :
825 0 : SwPaM* pCrsr = pPaM ? pPaM : GetCrsr();
826 0 : if( pCrsr->GetNext() != pCrsr ) // multiple selection ?
827 : {
828 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
829 0 : SwPamRanges aRangeArr( *pCrsr );
830 0 : SwPaM aPam( *pCrsr->GetPoint() );
831 0 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
832 0 : GetDoc()->SetNodeNumStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), nStt );
833 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
834 : }
835 : else
836 0 : GetDoc()->SetNodeNumStart( *pCrsr->GetPoint(), nStt );
837 :
838 0 : EndAllAction();
839 0 : }
840 :
841 0 : sal_uInt16 SwEditShell::GetNodeNumStart( SwPaM* pPaM ) const
842 : {
843 0 : SwPaM* pCrsr = pPaM ? pPaM : GetCrsr();
844 0 : const SwTxtNode* pTxtNd = pCrsr->GetNode().GetTxtNode();
845 : // correction: check, if list restart value is set at text node and
846 : // use new method <SwTxtNode::GetAttrListRestartValue()>.
847 : // return USHRT_MAX, if no list restart value is found.
848 0 : if ( pTxtNd && pTxtNd->HasAttrListRestartValue() )
849 : {
850 0 : return static_cast<sal_uInt16>(pTxtNd->GetAttrListRestartValue());
851 : }
852 0 : return USHRT_MAX;
853 : }
854 :
855 0 : const SwNumRule * SwEditShell::SearchNumRule( const bool bForward,
856 : const bool bNum,
857 : const bool bOutline,
858 : int nNonEmptyAllowed,
859 : OUString& sListId )
860 : {
861 0 : return GetDoc()->SearchNumRule( *(bForward ? GetCrsr()->End() : GetCrsr()->Start()),
862 : bForward, bNum, bOutline, nNonEmptyAllowed,
863 0 : sListId );
864 270 : }
865 :
866 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|