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