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