xref: /AOO41X/main/sw/source/core/doc/fmtcol.cxx (revision ff0525f24f03981d56b7579b645949f111420994)
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 #include <hintids.hxx>
27 #include <editeng/ulspitem.hxx>
28 #include <editeng/lrspitem.hxx>
29 #include <editeng/fhgtitem.hxx>
30 #include <doc.hxx>          // fuer GetAttrPool
31 #include <errhdl.hxx>
32 #include <fmtcol.hxx>
33 #include <fmtcolfunc.hxx>
34 #include <hints.hxx>
35 #include <calc.hxx>
36 #include <node.hxx>
37 #include <numrule.hxx>
38 #include <paratr.hxx>
39 #include <switerator.hxx>
40 #include <svl/intitem.hxx>
41 
42 TYPEINIT1( SwTxtFmtColl, SwFmtColl );
43 TYPEINIT1( SwGrfFmtColl, SwFmtColl );
44 TYPEINIT1( SwConditionTxtFmtColl, SwTxtFmtColl );
45 TYPEINIT1( SwCollCondition, SwClient );
46 
47 SV_IMPL_PTRARR( SwFmtCollConditions, SwCollConditionPtr );
48 
49 // --> OD 2008-03-04 #refactorlists#
50 namespace TxtFmtCollFunc
51 {
52 
53     // --> OD 2006-11-22 #i71574#
54     void CheckTxtFmtCollForDeletionOfAssignmentToOutlineStyle(
55                                             SwFmt* pFmt,
56                                             const SwNumRuleItem* pNewNumRuleItem )
57     {
58         SwTxtFmtColl* pTxtFmtColl = dynamic_cast<SwTxtFmtColl*>(pFmt);
59         if ( !pTxtFmtColl )
60         {
61     #if OSL_DEBUG_LEVEL > 1
62             ASSERT( false,
63                     "<TxtFmtCollFunc::CheckTxtFmtCollFuncForDeletionOfAssignmentToOutlineStyle> - misuse of method - it's only for instances of <SwTxtFmtColl>" );
64     #endif
65             return;
66         }
67 
68         // --> OD 2007-01-24 #i73790#
69     //    if ( pTxtFmtColl->AssignedToListLevelOfOutlineStyle() )
70         if ( !pTxtFmtColl->StayAssignedToListLevelOfOutlineStyle() &&
71              pTxtFmtColl->IsAssignedToListLevelOfOutlineStyle() )
72         // <--
73         {
74             if ( !pNewNumRuleItem )
75             {
76                 pTxtFmtColl->GetItemState( RES_PARATR_NUMRULE, sal_False, (const SfxPoolItem**)&pNewNumRuleItem );
77             }
78             if ( pNewNumRuleItem )
79             {
80                 String sNumRuleName = pNewNumRuleItem->GetValue();
81                 if ( sNumRuleName.Len() == 0 ||
82                      sNumRuleName != pTxtFmtColl->GetDoc()->GetOutlineNumRule()->GetName() )
83                 {
84                     // delete assignment of paragraph style to list level of outline style.
85                     pTxtFmtColl->DeleteAssignmentToListLevelOfOutlineStyle();
86                 }
87             }
88         }
89     }
90     // <--
91 
92     SwNumRule* GetNumRule( SwTxtFmtColl& rTxtFmtColl )
93     {
94         SwNumRule* pNumRule( 0 );
95 
96         const SwNumRuleItem* pNumRuleItem( 0 );
97         rTxtFmtColl.GetItemState( RES_PARATR_NUMRULE, sal_False, (const SfxPoolItem**)&pNumRuleItem );
98         if ( pNumRuleItem )
99         {
100             const String sNumRuleName = pNumRuleItem->GetValue();
101             if ( sNumRuleName.Len() > 0 )
102             {
103                 pNumRule = rTxtFmtColl.GetDoc()->FindNumRulePtr( sNumRuleName );
104             }
105         }
106 
107         return pNumRule;
108     }
109 
110     void AddToNumRule( SwTxtFmtColl& rTxtFmtColl )
111     {
112         SwNumRule* pNumRule = GetNumRule( rTxtFmtColl );
113         if ( pNumRule )
114         {
115             pNumRule->AddParagraphStyle( rTxtFmtColl );
116         }
117     }
118 
119     void RemoveFromNumRule( SwTxtFmtColl& rTxtFmtColl )
120     {
121         SwNumRule* pNumRule = GetNumRule( rTxtFmtColl );
122         if ( pNumRule )
123         {
124             pNumRule->RemoveParagraphStyle( rTxtFmtColl );
125         }
126     }
127 } // end of namespace TxtFmtCollFunc
128 // <--
129 
130 /*
131  * SwTxtFmtColl  TXT
132  */
133 
134 void SwTxtFmtColl::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
135 {
136     if( GetDoc()->IsInDtor() )
137     {
138         SwFmtColl::Modify( pOld, pNew );
139         return;
140     }
141 
142     // --> OD 2006-06-16 #i66431# - adjust type of <bNewParent>
143     bool bNewParent( false );
144     // <--
145     SvxULSpaceItem *pNewULSpace = 0, *pOldULSpace = 0;
146     SvxLRSpaceItem *pNewLRSpace = 0, *pOldLRSpace = 0;
147     SvxFontHeightItem* aFontSizeArr[3] = {0,0,0};
148     // --> OD 2006-10-17 #i70223#
149     const bool bAssignedToListLevelOfOutlineStyle(IsAssignedToListLevelOfOutlineStyle());//#outline level ,zhaojianwei
150     const SwNumRuleItem* pNewNumRuleItem( 0L );
151     // <--
152 
153     SwAttrSetChg *pNewChgSet = 0,  *pOldChgSet = 0;
154 
155     switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 )
156     {
157     case RES_ATTRSET_CHG:
158         // nur neu berechnen, wenn nicht wir der "Versender" sind !!!
159         pNewChgSet = (SwAttrSetChg*)pNew;
160         pOldChgSet = (SwAttrSetChg*)pOld;
161         pNewChgSet->GetChgSet()->GetItemState(
162             RES_LR_SPACE, sal_False, (const SfxPoolItem**)&pNewLRSpace );
163         pNewChgSet->GetChgSet()->GetItemState(
164             RES_UL_SPACE, sal_False, (const SfxPoolItem**)&pNewULSpace );
165         pNewChgSet->GetChgSet()->GetItemState( RES_CHRATR_FONTSIZE,
166                         sal_False, (const SfxPoolItem**)&(aFontSizeArr[0]) );
167         pNewChgSet->GetChgSet()->GetItemState( RES_CHRATR_CJK_FONTSIZE,
168                         sal_False, (const SfxPoolItem**)&(aFontSizeArr[1]) );
169         pNewChgSet->GetChgSet()->GetItemState( RES_CHRATR_CTL_FONTSIZE,
170                         sal_False, (const SfxPoolItem**)&(aFontSizeArr[2]) );
171         // --> OD 2006-10-17 #i70223#
172         // --> OD 2007-12-19 #i84745#
173         // check, if attribute set is applied to this paragraph style
174         if ( bAssignedToListLevelOfOutlineStyle &&
175              pNewChgSet->GetTheChgdSet() == &GetAttrSet() )
176         {
177             pNewChgSet->GetChgSet()->GetItemState( RES_PARATR_NUMRULE, sal_False,
178                                                    (const SfxPoolItem**)&pNewNumRuleItem );
179         }
180         // <--
181 
182         break;
183 
184     case RES_FMT_CHG:
185         if( GetAttrSet().GetParent() )
186         {
187             const SfxItemSet* pParent = GetAttrSet().GetParent();
188             pNewLRSpace = (SvxLRSpaceItem*)&pParent->Get( RES_LR_SPACE );
189             pNewULSpace = (SvxULSpaceItem*)&pParent->Get( RES_UL_SPACE );
190             aFontSizeArr[0] = (SvxFontHeightItem*)&pParent->Get( RES_CHRATR_FONTSIZE );
191             aFontSizeArr[1] = (SvxFontHeightItem*)&pParent->Get( RES_CHRATR_CJK_FONTSIZE );
192             aFontSizeArr[2] = (SvxFontHeightItem*)&pParent->Get( RES_CHRATR_CTL_FONTSIZE );
193             // --> OD 2006-06-16 #i66431#
194             // modify has to be propagated, because of new parent format.
195             bNewParent = true;
196             // <--
197         }
198         break;
199 
200     case RES_LR_SPACE:
201         pNewLRSpace = (SvxLRSpaceItem*)pNew;
202         break;
203     case RES_UL_SPACE:
204         pNewULSpace = (SvxULSpaceItem*)pNew;
205         break;
206     case RES_CHRATR_FONTSIZE:
207         aFontSizeArr[0] = (SvxFontHeightItem*)pNew;
208         break;
209     case RES_CHRATR_CJK_FONTSIZE:
210         aFontSizeArr[1] = (SvxFontHeightItem*)pNew;
211         break;
212     case RES_CHRATR_CTL_FONTSIZE:
213         aFontSizeArr[2] = (SvxFontHeightItem*)pNew;
214         break;
215     // --> OD 2006-10-17 #i70223#
216     case RES_PARATR_NUMRULE:
217     {
218         if ( bAssignedToListLevelOfOutlineStyle )
219         {
220             pNewNumRuleItem = (SwNumRuleItem*)pNew;
221         }
222     }
223     default:
224         break;
225     }
226 
227     // --> OD 2006-10-17 #i70223#
228     if ( bAssignedToListLevelOfOutlineStyle && pNewNumRuleItem )
229     {
230         TxtFmtCollFunc::CheckTxtFmtCollForDeletionOfAssignmentToOutlineStyle(
231                                                         this, pNewNumRuleItem );
232     }
233     // <--
234 
235     int bWeiter = sal_True;
236 
237     // dann pruefe doch mal gegen die eigenen Attribute
238     if( pNewLRSpace && SFX_ITEM_SET == GetItemState( RES_LR_SPACE, sal_False,
239                                         (const SfxPoolItem**)&pOldLRSpace ))
240     {
241         int bChg = sal_False;
242         if( pOldLRSpace != pNewLRSpace )    // verhinder Rekursion (SetAttr!!)
243         {
244             SvxLRSpaceItem aNew( *pOldLRSpace );
245             // wir hatten eine relative Angabe -> neu berechnen
246             if( 100 != aNew.GetPropLeft() )
247             {
248                 long nTmp = aNew.GetLeft();     // alten zum Vergleichen
249                 aNew.SetLeft( pNewLRSpace->GetLeft(), aNew.GetPropLeft() );
250                 bChg |= nTmp != aNew.GetLeft();
251             }
252             // wir hatten eine relative Angabe -> neu berechnen
253             if( 100 != aNew.GetPropRight() )
254             {
255                 long nTmp = aNew.GetRight();        // alten zum Vergleichen
256                 aNew.SetRight( pNewLRSpace->GetRight(), aNew.GetPropRight() );
257                 bChg |= nTmp != aNew.GetRight();
258             }
259             // wir hatten eine relative Angabe -> neu berechnen
260             if( 100 != aNew.GetPropTxtFirstLineOfst() )
261             {
262                 short nTmp = aNew.GetTxtFirstLineOfst();        // alten zum Vergleichen
263                 aNew.SetTxtFirstLineOfst( pNewLRSpace->GetTxtFirstLineOfst(),
264                                             aNew.GetPropTxtFirstLineOfst() );
265                 bChg |= nTmp != aNew.GetTxtFirstLineOfst();
266             }
267             if( bChg )
268             {
269                 SetFmtAttr( aNew );
270                 bWeiter = 0 != pOldChgSet || bNewParent;
271             }
272             // bei uns absolut gesetzt -> nicht weiter propagieren, es sei
273             // denn es wird bei uns gesetzt!
274             else if( pNewChgSet )
275                 bWeiter = pNewChgSet->GetTheChgdSet() == &GetAttrSet();
276         }
277     }
278 
279     if( pNewULSpace && SFX_ITEM_SET == GetItemState(
280             RES_UL_SPACE, sal_False, (const SfxPoolItem**)&pOldULSpace ) &&
281         pOldULSpace != pNewULSpace )    // verhinder Rekursion (SetAttr!!)
282     {
283         SvxULSpaceItem aNew( *pOldULSpace );
284         int bChg = sal_False;
285         // wir hatten eine relative Angabe -> neu berechnen
286         if( 100 != aNew.GetPropUpper() )
287         {
288             sal_uInt16 nTmp = aNew.GetUpper();      // alten zum Vergleichen
289             aNew.SetUpper( pNewULSpace->GetUpper(), aNew.GetPropUpper() );
290             bChg |= nTmp != aNew.GetUpper();
291         }
292         // wir hatten eine relative Angabe -> neu berechnen
293         if( 100 != aNew.GetPropLower() )
294         {
295             sal_uInt16 nTmp = aNew.GetLower();      // alten zum Vergleichen
296             aNew.SetLower( pNewULSpace->GetLower(), aNew.GetPropLower() );
297             bChg |= nTmp != aNew.GetLower();
298         }
299         if( bChg )
300         {
301             SetFmtAttr( aNew );
302             bWeiter = 0 != pOldChgSet || bNewParent;
303         }
304         // bei uns absolut gesetzt -> nicht weiter propagieren, es sei
305         // denn es wird bei uns gesetzt!
306         else if( pNewChgSet )
307             bWeiter = pNewChgSet->GetTheChgdSet() == &GetAttrSet();
308     }
309 
310 
311     for( int nC = 0, nArrLen = sizeof(aFontSizeArr) / sizeof( aFontSizeArr[0]);
312             nC < nArrLen; ++nC )
313     {
314         SvxFontHeightItem *pFSize = aFontSizeArr[ nC ], *pOldFSize;
315         if( pFSize && SFX_ITEM_SET == GetItemState(
316             pFSize->Which(), sal_False, (const SfxPoolItem**)&pOldFSize ) &&
317             // verhinder Rekursion (SetAttr!!)
318             pFSize != pOldFSize )
319         {
320             if( 100 == pOldFSize->GetProp() &&
321                 SFX_MAPUNIT_RELATIVE == pOldFSize->GetPropUnit() )
322             {
323                 // bei uns absolut gesetzt -> nicht weiter propagieren, es sei
324                 // denn es wird bei uns gesetzt!
325                 if( pNewChgSet )
326                     bWeiter = pNewChgSet->GetTheChgdSet() == &GetAttrSet();
327             }
328             else
329             {
330                 // wir hatten eine relative Angabe -> neu berechnen
331                 sal_uInt32 nTmp = pOldFSize->GetHeight();       // alten zum Vergleichen
332                 SvxFontHeightItem aNew(240 , 100, pFSize->Which());
333                 aNew.SetHeight( pFSize->GetHeight(), pOldFSize->GetProp(),
334                                 pOldFSize->GetPropUnit() );
335                 if( nTmp != aNew.GetHeight() )
336                 {
337                     SetFmtAttr( aNew );
338                     bWeiter = 0 != pOldChgSet || bNewParent;
339                 }
340                 // bei uns absolut gesetzt -> nicht weiter propagieren, es sei
341                 // denn es wird bei uns gesetzt!
342                 else if( pNewChgSet )
343                     bWeiter = pNewChgSet->GetTheChgdSet() == &GetAttrSet();
344             }
345         }
346     }
347 
348     if( bWeiter )
349         SwFmtColl::Modify( pOld, pNew );
350 }
351 
352 sal_Bool SwTxtFmtColl::IsAtDocNodeSet() const
353 {
354     SwIterator<SwCntntNode,SwFmtColl> aIter( *this );
355     const SwNodes& rNds = GetDoc()->GetNodes();
356     for( SwCntntNode* pNode = aIter.First(); pNode; pNode = aIter.Next() )
357         if( &(pNode->GetNodes()) == &rNds )
358             return sal_True;
359 
360     return sal_False;
361 }
362 
363 // --> OD 2008-03-04 #refactorlists#
364 sal_Bool SwTxtFmtColl::SetFmtAttr( const SfxPoolItem& rAttr )
365 {
366     const bool bIsNumRuleItem = rAttr.Which() == RES_PARATR_NUMRULE;
367     if ( bIsNumRuleItem )
368     {
369         TxtFmtCollFunc::RemoveFromNumRule( *this );
370     }
371 
372     const sal_Bool bRet = SwFmtColl::SetFmtAttr( rAttr );
373 
374     if ( bIsNumRuleItem )
375     {
376         TxtFmtCollFunc::AddToNumRule( *this );
377     }
378 
379     return bRet;
380 }
381 
382 sal_Bool SwTxtFmtColl::SetFmtAttr( const SfxItemSet& rSet )
383 {
384     const bool bIsNumRuleItemAffected =
385                 rSet.GetItemState( RES_PARATR_NUMRULE, sal_False ) == SFX_ITEM_SET;
386     if ( bIsNumRuleItemAffected )
387     {
388         TxtFmtCollFunc::RemoveFromNumRule( *this );
389     }
390 
391     const sal_Bool bRet = SwFmtColl::SetFmtAttr( rSet );
392 
393     if ( bIsNumRuleItemAffected )
394     {
395         TxtFmtCollFunc::AddToNumRule( *this );
396     }
397 
398     return bRet;
399 }
400 
401 sal_Bool SwTxtFmtColl::ResetFmtAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
402 {
403     const bool bIsNumRuleItemAffected =
404                 ( nWhich2 != 0 && nWhich2 > nWhich1 )
405                 ? ( nWhich1 <= RES_PARATR_NUMRULE &&
406                     RES_PARATR_NUMRULE <= nWhich2 )
407                 : nWhich1 == RES_PARATR_NUMRULE;
408     if ( bIsNumRuleItemAffected )
409     {
410         TxtFmtCollFunc::RemoveFromNumRule( *this );
411     }
412 
413     const sal_Bool bRet = SwFmtColl::ResetFmtAttr( nWhich1, nWhich2 );
414 
415     return bRet;
416 }
417 // <--
418 
419 // --> OD 2007-01-24 #i73790#
420 sal_uInt16 SwTxtFmtColl::ResetAllFmtAttr()
421 {
422     const bool bOldState( mbStayAssignedToListLevelOfOutlineStyle );
423     mbStayAssignedToListLevelOfOutlineStyle = true;
424     // --> OD 2008-12-16 #i70748#
425     // Outline level is no longer a member, it is a attribute now.
426     // Thus, it needs to be restored, if the paragraph style is assigned
427     // to the outline style
428     const int nAssignedOutlineStyleLevel = IsAssignedToListLevelOfOutlineStyle()
429                                      ? GetAssignedOutlineStyleLevel()
430                                      : -1;
431     // <--
432 
433     sal_uInt16 nRet = SwFmtColl::ResetAllFmtAttr();
434 
435     // --> OD 2008-12-16 #i70748#
436     if ( nAssignedOutlineStyleLevel != -1 )
437     {
438         AssignToListLevelOfOutlineStyle( nAssignedOutlineStyleLevel );
439     }
440     // <--
441 
442     mbStayAssignedToListLevelOfOutlineStyle = bOldState;
443 
444     return nRet;
445 }
446 // <--
447 
448 // --> OD 2008-02-13 #newlistlevelattrs#
449 bool SwTxtFmtColl::AreListLevelIndentsApplicable() const
450 {
451     bool bAreListLevelIndentsApplicable( true );
452 
453     if ( GetItemState( RES_PARATR_NUMRULE ) != SFX_ITEM_SET )
454     {
455         // no list style applied to paragraph style
456         bAreListLevelIndentsApplicable = false;
457     }
458     else if ( GetItemState( RES_LR_SPACE, sal_False ) == SFX_ITEM_SET )
459     {
460         // paragraph style has hard-set indent attributes
461         bAreListLevelIndentsApplicable = false;
462     }
463     else if ( GetItemState( RES_PARATR_NUMRULE, sal_False ) == SFX_ITEM_SET )
464     {
465         // list style is directly applied to paragraph style and paragraph
466         // style has no hard-set indent attributes
467         bAreListLevelIndentsApplicable = true;
468     }
469     else
470     {
471         // list style is applied through one of the parent paragraph styles and
472         // paragraph style has no hard-set indent attributes
473 
474         // check parent paragraph styles
475         const SwTxtFmtColl* pColl = dynamic_cast<const SwTxtFmtColl*>(DerivedFrom());
476         while ( pColl )
477         {
478             if ( pColl->GetAttrSet().GetItemState( RES_LR_SPACE, sal_False ) == SFX_ITEM_SET )
479             {
480                 // indent attributes found in the paragraph style hierarchy.
481                 bAreListLevelIndentsApplicable = false;
482                 break;
483             }
484 
485             if ( pColl->GetAttrSet().GetItemState( RES_PARATR_NUMRULE, sal_False ) == SFX_ITEM_SET )
486             {
487                 // paragraph style with the list style found and until now no
488                 // indent attributes are found in the paragraph style hierarchy.
489                 bAreListLevelIndentsApplicable = true;
490                 break;
491             }
492 
493             pColl = dynamic_cast<const SwTxtFmtColl*>(pColl->DerivedFrom());
494             ASSERT( pColl,
495                     "<SwTxtFmtColl::AreListLevelIndentsApplicable()> - something wrong in paragraph style hierarchy. The applied list style is not found." );
496         }
497     }
498 
499     return bAreListLevelIndentsApplicable;
500 }
501 // <--
502 
503 //FEATURE::CONDCOLL
504 
505 SwCollCondition::SwCollCondition( SwTxtFmtColl* pColl, sal_uLong nMasterCond,
506                                 sal_uLong nSubCond )
507     : SwClient( pColl ), nCondition( nMasterCond )
508 {
509     aSubCondition.nSubCondition = nSubCond;
510 }
511 
512 
513 SwCollCondition::SwCollCondition( SwTxtFmtColl* pColl, sal_uLong nMasterCond,
514                                     const String& rSubExp )
515     : SwClient( pColl ), nCondition( nMasterCond )
516 {
517     if( USRFLD_EXPRESSION & nCondition )
518         aSubCondition.pFldExpression = new String( rSubExp );
519     else
520         aSubCondition.nSubCondition = 0;
521 }
522 
523 
524 SwCollCondition::SwCollCondition( const SwCollCondition& rCopy )
525     : SwClient( (SwModify*)rCopy.GetRegisteredIn() ), nCondition( rCopy.nCondition )
526 {
527     if( USRFLD_EXPRESSION & rCopy.nCondition )
528         aSubCondition.pFldExpression = new String( *rCopy.GetFldExpression() );
529     else
530         aSubCondition.nSubCondition = rCopy.aSubCondition.nSubCondition;
531 }
532 
533 
534 SwCollCondition::~SwCollCondition()
535 {
536     if( USRFLD_EXPRESSION & nCondition )
537         delete aSubCondition.pFldExpression;
538 }
539 
540 void SwCollCondition::RegisterToFormat( SwFmt& rFmt )
541 {
542     rFmt.Add( this );
543 }
544 
545 
546 
547 int SwCollCondition::operator==( const SwCollCondition& rCmp ) const
548 {
549     int nRet = 0;
550     if( nCondition == rCmp.nCondition )
551     {
552         if( USRFLD_EXPRESSION & nCondition )
553         {
554             // in der SubCondition steht die Expression fuer das UserFeld
555             const String* pTmp = aSubCondition.pFldExpression;
556             if( !pTmp )
557                 pTmp = rCmp.aSubCondition.pFldExpression;
558             if( pTmp )
559             {
560                 SwTxtFmtColl* pColl = GetTxtFmtColl();
561                 if( !pColl )
562                     pColl = rCmp.GetTxtFmtColl();
563 
564                 if( pColl )
565                 {
566                     SwCalc aCalc( *pColl->GetDoc() );
567                     nRet = 0 != aCalc.Calculate( *pTmp ).GetBool();
568                 }
569             }
570         }
571         else if( aSubCondition.nSubCondition ==
572                     rCmp.aSubCondition.nSubCondition )
573             nRet = 1;
574     }
575     return nRet;
576 }
577 
578 
579 void SwCollCondition::SetCondition( sal_uLong nCond, sal_uLong nSubCond )
580 {
581     if( USRFLD_EXPRESSION & nCondition )
582         delete aSubCondition.pFldExpression;
583     nCondition = nCond;
584     aSubCondition.nSubCondition = nSubCond;
585 }
586 
587 
588 SwConditionTxtFmtColl::~SwConditionTxtFmtColl()
589 {
590 }
591 
592 const SwCollCondition* SwConditionTxtFmtColl::HasCondition(
593                         const SwCollCondition& rCond ) const
594 {
595     const SwCollCondition* pFnd = 0;
596     sal_uInt16 n;
597 
598     for( n = 0; n < aCondColls.Count(); ++n )
599         if( *( pFnd = aCondColls[ n ]) == rCond )
600             break;
601 
602     return n < aCondColls.Count() ? pFnd : 0;
603 }
604 
605 
606 void SwConditionTxtFmtColl::InsertCondition( const SwCollCondition& rCond )
607 {
608     for( sal_uInt16 n = 0; n < aCondColls.Count(); ++n )
609         if( *aCondColls[ n ] == rCond )
610         {
611             aCondColls.DeleteAndDestroy( n );
612             break;
613         }
614 
615     // nicht gefunden -> als einfuegen
616     SwCollCondition* pNew = new SwCollCondition( rCond );
617     aCondColls.Insert( pNew, aCondColls.Count() );
618 }
619 
620 
621 sal_Bool SwConditionTxtFmtColl::RemoveCondition( const SwCollCondition& rCond )
622 {
623     sal_Bool bRet = sal_False;
624     for( sal_uInt16 n = 0; n < aCondColls.Count(); ++n )
625         if( *aCondColls[ n ] == rCond )
626         {
627             aCondColls.DeleteAndDestroy( n );
628             bRet = sal_True;
629         }
630 
631     return bRet;
632 }
633 
634 void SwConditionTxtFmtColl::SetConditions( const SwFmtCollConditions& rCndClls )
635 {
636     // Kopiere noch die Bedingungen
637     // aber erst die alten loeschen!
638     if( aCondColls.Count() )
639         aCondColls.DeleteAndDestroy( 0, aCondColls.Count() );
640     SwDoc& rDoc = *GetDoc();
641     for( sal_uInt16 n = 0; n < rCndClls.Count(); ++n )
642     {
643         SwCollCondition* pFnd = rCndClls[ n ];
644         SwTxtFmtColl* pTmpColl = pFnd->GetTxtFmtColl()
645                                     ? rDoc.CopyTxtColl( *pFnd->GetTxtFmtColl() )
646                                     : 0;
647         SwCollCondition* pNew;
648         if( USRFLD_EXPRESSION & pFnd->GetCondition() )
649             pNew = new SwCollCondition( pTmpColl, pFnd->GetCondition(),
650                                         *pFnd->GetFldExpression() );
651         else
652             pNew = new SwCollCondition( pTmpColl, pFnd->GetCondition(),
653                                         pFnd->GetSubCondition() );
654         aCondColls.Insert( pNew, n );
655     }
656 }
657 //#outline level, zhaojianwei
658 void SwTxtFmtColl::SetAttrOutlineLevel( int nLevel)
659 {
660     ASSERT( 0 <= nLevel && nLevel <= MAXLEVEL ,"SwTxtFmtColl: Level Out Of Range" );
661     SetFmtAttr( SfxUInt16Item( RES_PARATR_OUTLINELEVEL,
662                             static_cast<sal_uInt16>(nLevel) ) );
663 }
664 
665 int SwTxtFmtColl::GetAttrOutlineLevel() const
666 {
667     return ((const SfxUInt16Item &)GetFmtAttr(RES_PARATR_OUTLINELEVEL)).GetValue();
668 }
669 
670 int SwTxtFmtColl::GetAssignedOutlineStyleLevel() const
671 {
672     ASSERT( IsAssignedToListLevelOfOutlineStyle(),
673         "<SwTxtFmtColl::GetAssignedOutlineStyleLevel()> - misuse of method");
674     return GetAttrOutlineLevel() - 1;
675 }
676 
677 void SwTxtFmtColl::AssignToListLevelOfOutlineStyle(const int nAssignedListLevel)
678 {
679     mbAssignedToOutlineStyle = true;
680     SetAttrOutlineLevel(nAssignedListLevel+1);
681 
682     // --> OD 2009-03-18 #i100277#
683     SwIterator<SwTxtFmtColl,SwFmtColl> aIter( *this );
684     SwTxtFmtColl* pDerivedTxtFmtColl = aIter.First();
685     while ( pDerivedTxtFmtColl != 0 )
686     {
687         if ( !pDerivedTxtFmtColl->IsAssignedToListLevelOfOutlineStyle() )
688         {
689             if ( pDerivedTxtFmtColl->GetItemState( RES_PARATR_NUMRULE, sal_False ) == SFX_ITEM_DEFAULT )
690             {
691                 SwNumRuleItem aItem(aEmptyStr);
692                 pDerivedTxtFmtColl->SetFmtAttr( aItem );
693             }
694             if ( pDerivedTxtFmtColl->GetItemState( RES_PARATR_OUTLINELEVEL, sal_False ) == SFX_ITEM_DEFAULT )
695             {
696                 pDerivedTxtFmtColl->SetAttrOutlineLevel( 0 );
697             }
698         }
699 
700         pDerivedTxtFmtColl = aIter.Next();
701     }
702     // <--
703 }
704 
705 void SwTxtFmtColl::DeleteAssignmentToListLevelOfOutlineStyle()
706 {
707     mbAssignedToOutlineStyle = false;
708     ResetFmtAttr(RES_PARATR_OUTLINELEVEL);
709 }
710 //<-end,zhaojianwei
711 
712 //FEATURE::CONDCOLL
713