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