xref: /aoo42x/main/sw/source/core/doc/docfmt.cxx (revision 56b35d86)
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 
27 
28 #define _ZFORLIST_DECLARE_TABLE
29 #define _SVSTDARR_USHORTSSORT
30 #define _SVSTDARR_USHORTS
31 #include <hintids.hxx>
32 #include <rtl/logfile.hxx>
33 #include <svl/itemiter.hxx>
34 #include <sfx2/app.hxx>
35 #include <editeng/tstpitem.hxx>
36 #include <editeng/eeitem.hxx>
37 #include <editeng/langitem.hxx>
38 #include <editeng/lrspitem.hxx>
39 #include <editeng/brkitem.hxx>
40 #include <svl/whiter.hxx>
41 #ifndef _ZFORLIST_HXX //autogen
42 #define _ZFORLIST_DECLARE_TABLE
43 #include <svl/zforlist.hxx>
44 #endif
45 #include <comphelper/processfactory.hxx>
46 #include <unotools/misccfg.hxx>
47 #include <com/sun/star/i18n/WordType.hdl>
48 #include <fmtpdsc.hxx>
49 #include <fmthdft.hxx>
50 #include <fmtcntnt.hxx>
51 #include <frmatr.hxx>
52 #include <doc.hxx>
53 #include <IDocumentUndoRedo.hxx>
54 #include <rootfrm.hxx>
55 #include <pagefrm.hxx>
56 #include <hints.hxx>			// fuer SwHyphenBug (in SetDefault)
57 #include <ndtxt.hxx>
58 #include <pam.hxx>
59 #include <UndoCore.hxx>
60 #include <UndoAttribute.hxx>
61 #include <ndgrf.hxx>
62 #include <pagedesc.hxx>			// Fuer Sonderbehandlung in InsFrmFmt
63 #include <rolbck.hxx>			// Undo-Attr
64 #include <mvsave.hxx>			// servieren: Veraenderungen erkennen
65 #include <txatbase.hxx>
66 #include <swtable.hxx>
67 #include <swtblfmt.hxx>
68 #include <charfmt.hxx>
69 #include <docary.hxx>
70 #include <paratr.hxx>
71 #include <redline.hxx>
72 #include <reffld.hxx>
73 #include <txtinet.hxx>
74 #include <fmtinfmt.hxx>
75 #include <breakit.hxx>
76 #include <SwStyleNameMapper.hxx>
77 #include <fmtautofmt.hxx>
78 #include <istyleaccess.hxx>
79 #include <SwUndoFmt.hxx>
80 #include <docsh.hxx>
81 
82 using namespace ::com::sun::star::i18n;
83 using namespace ::com::sun::star::lang;
84 using namespace ::com::sun::star::uno;
85 
86 SV_IMPL_PTRARR(SwFrmFmts,SwFrmFmtPtr)
87 SV_IMPL_PTRARR(SwCharFmts,SwCharFmtPtr)
88 
89 //Spezifische Frameformate (Rahmen)
90 SV_IMPL_PTRARR(SwSpzFrmFmts,SwFrmFmtPtr)
91 
92 /*
93  * interne Funktionen
94  */
95 
96 sal_Bool SetTxtFmtCollNext( const SwTxtFmtCollPtr& rpTxtColl, void* pArgs )
97 {
98 	SwTxtFmtColl *pDel = (SwTxtFmtColl*) pArgs;
99 	if ( &rpTxtColl->GetNextTxtFmtColl() == pDel )
100 	{
101 		rpTxtColl->SetNextTxtFmtColl( *rpTxtColl );
102 	}
103 	return sal_True;
104 }
105 
106 /*
107  * Zuruecksetzen der harten Formatierung fuer Text
108  */
109 
110 // Uebergabeparameter fuer _Rst und lcl_SetTxtFmtColl
111 struct ParaRstFmt
112 {
113 	SwFmtColl* pFmtColl;
114 	SwHistory* pHistory;
115 	const SwPosition *pSttNd, *pEndNd;
116 	const SfxItemSet* pDelSet;
117 	sal_uInt16 nWhich;
118     bool bReset;
119     // --> OD 2007-11-06 #i62575#
120     bool bResetListAttrs;
121     // <--
122     bool bResetAll;
123     bool bInclRefToxMark;
124 
125 	bool bKeepOutlineLevelAttr;	//#outline level,add by zhaojianwei
126 
127 	ParaRstFmt( const SwPosition* pStt, const SwPosition* pEnd,
128                 SwHistory* pHst, sal_uInt16 nWhch = 0, const SfxItemSet* pSet = 0 )
129         : pFmtColl(0),
130           pHistory(pHst),
131           pSttNd(pStt),
132           pEndNd(pEnd),
133           pDelSet(pSet),
134           nWhich(nWhch),
135           // --> OD 2007-11-06 #i62675#
136           bReset( false ),
137           bResetListAttrs( false ),
138           // <--
139           bResetAll( true ),
140           bInclRefToxMark( false ),
141 		  bKeepOutlineLevelAttr( false )	//#outline level,add by zhaojianwei
142 	{}
143 
144 	ParaRstFmt( SwHistory* pHst )
145         : pFmtColl(0),
146           pHistory(pHst),
147           pSttNd(0),
148           pEndNd(0),
149           pDelSet(0),
150           nWhich(0),
151           // --> OD 2007-11-06 #i62675#
152           bReset( false ),
153           bResetListAttrs( false ),
154           // <--
155           bResetAll( true ),
156           bInclRefToxMark( false ),
157   		  bKeepOutlineLevelAttr( false )	//#outline level,add by zhaojianwei
158 	{}
159 };
160 
161 /* in pArgs steht die ChrFmtTablle vom Dokument
162  * (wird bei Selectionen am Start/Ende und bei keiner SSelection benoetigt)
163  */
164 
165 sal_Bool lcl_RstTxtAttr( const SwNodePtr& rpNd, void* pArgs )
166 {
167     ParaRstFmt* pPara = (ParaRstFmt*)pArgs;
168     SwTxtNode * pTxtNode = (SwTxtNode*)rpNd->GetTxtNode();
169     if( pTxtNode && pTxtNode->GetpSwpHints() )
170     {
171         SwIndex aSt( pTxtNode, 0 );
172         sal_uInt16 nEnd = pTxtNode->Len();
173 
174         if( &pPara->pSttNd->nNode.GetNode() == pTxtNode &&
175             pPara->pSttNd->nContent.GetIndex() )
176             aSt = pPara->pSttNd->nContent.GetIndex();
177 
178         if( &pPara->pEndNd->nNode.GetNode() == rpNd )
179             nEnd = pPara->pEndNd->nContent.GetIndex();
180 
181         if( pPara->pHistory )
182         {
183             // fuers Undo alle Attribute sichern
184             SwRegHistory aRHst( *pTxtNode, pPara->pHistory );
185             pTxtNode->GetpSwpHints()->Register( &aRHst );
186             pTxtNode->RstTxtAttr( aSt, nEnd - aSt.GetIndex(), pPara->nWhich,
187                                   pPara->pDelSet, pPara->bInclRefToxMark );
188             if( pTxtNode->GetpSwpHints() )
189                 pTxtNode->GetpSwpHints()->DeRegister();
190         }
191         else
192             pTxtNode->RstTxtAttr( aSt, nEnd - aSt.GetIndex(), pPara->nWhich,
193                                   pPara->pDelSet, pPara->bInclRefToxMark );
194     }
195     return sal_True;
196 }
197 
198 sal_Bool lcl_RstAttr( const SwNodePtr& rpNd, void* pArgs )
199 {
200 	ParaRstFmt* pPara = (ParaRstFmt*)pArgs;
201 	SwCntntNode* pNode = (SwCntntNode*)rpNd->GetCntntNode();
202     if( pNode && pNode->HasSwAttrSet() )
203 	{
204         const sal_Bool bLocked = pNode->IsModifyLocked();
205         pNode->LockModify();
206 
207         SwDoc* pDoc = pNode->GetDoc();
208 
209         // --> OD 2008-04-14 #refactorlists#
210         // remove unused attribute RES_LR_SPACE
211         // add list attributes
212 		SfxItemSet aSet( pDoc->GetAttrPool(),
213                          RES_PAGEDESC, RES_BREAK,
214                          RES_PARATR_NUMRULE, RES_PARATR_NUMRULE,
215 						 RES_PARATR_OUTLINELEVEL,RES_PARATR_OUTLINELEVEL,//#outline level,removed by zhaojianwei
216                          RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1,
217                          0 );
218         const SfxItemSet* pSet = pNode->GetpSwAttrSet();
219 
220         // --> OD 2008-04-15 #refactorlists#
221 //        std::vector<sal_uInt16> aClearWhichIds;
222         SvUShorts aClearWhichIds;
223         // <--
224         // --> OD 2008-04-15 #refactorlists#
225         // restoring all paragraph list attributes
226         {
227             SfxItemSet aListAttrSet( pDoc->GetAttrPool(),
228                                      RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1,
229                                      0 );
230             aListAttrSet.Set( *pSet );
231             if ( aListAttrSet.Count() )
232             {
233                 aSet.Put( aListAttrSet );
234                 SfxItemIter aIter( aListAttrSet );
235                 const SfxPoolItem* pItem = aIter.GetCurItem();
236                 while( pItem )
237                 {
238                     aClearWhichIds.Insert( pItem->Which(), aClearWhichIds.Count() );
239                     pItem = aIter.NextItem();
240                 }
241             }
242         }
243         // <--
244 
245 		const SfxPoolItem* pItem;
246   //      sal_uInt16 __READONLY_DATA aSavIds[ 3 ] = { RES_PAGEDESC, RES_BREAK,	//#outline level,removed by zhaojianwei
247   //                                              RES_PARATR_NUMRULE };
248 		//for( sal_uInt16 n = 0; n < 3; ++n )
249         sal_uInt16 __READONLY_DATA aSavIds[ 4 ] = { RES_PAGEDESC, RES_BREAK,	//->add by zhaojianwei
250                                                 RES_PARATR_NUMRULE,
251 												RES_PARATR_OUTLINELEVEL };
252 		for( sal_uInt16 n = 0; n < 4; ++n )										//<-end,zhaojianwei
253         {
254 			if( SFX_ITEM_SET == pSet->GetItemState( aSavIds[ n ], sal_False, &pItem ))
255 			{
256                 bool bSave = false;
257 				switch( aSavIds[ n ] )
258 				{
259                     case RES_PAGEDESC:
260                         bSave = 0 != ((SwFmtPageDesc*)pItem)->GetPageDesc();
261                     break;
262                     case RES_BREAK:
263                         bSave = SVX_BREAK_NONE != ((SvxFmtBreakItem*)pItem)->GetBreak();
264                     break;
265                     case RES_PARATR_NUMRULE:
266                     {
267                         bSave = 0 != ((SwNumRuleItem*)pItem)->GetValue().Len();
268                     }
269                     break;
270 					case RES_PARATR_OUTLINELEVEL:				//#outline level,add by zhaojianwei
271 					{
272 						bSave = pPara && pPara->bKeepOutlineLevelAttr;
273 					}
274 					break;										//<-end,zhaojianwei
275 				}
276 				if( bSave )
277 				{
278 					aSet.Put( *pItem );
279                     // --> OD 2008-04-15 #refactorlists#
280 //                    aClearWhichIds.push_back( aSavIds[n] );
281                     aClearWhichIds.Insert( aSavIds[n], aClearWhichIds.Count() );
282                 }
283 			}
284         }
285 
286         // --> OD 2008-04-14 #refactorlists#
287         // do not clear items directly from item set and only clear to be kept
288         // attributes, if no deletion item set is found.
289 //        pNode->ClearItemsFromAttrSet( aClearWhichIds );
290         const bool bKeepAttributes =
291                     !pPara || !pPara->pDelSet || pPara->pDelSet->Count() == 0;
292         if ( bKeepAttributes )
293         {
294             pNode->ResetAttr( aClearWhichIds );
295         }
296         // <--
297 
298         if( !bLocked )
299             pNode->UnlockModify();
300 
301 		if( pPara )
302 		{
303 			SwRegHistory aRegH( pNode, *pNode, pPara->pHistory );
304 
305 			if( pPara->pDelSet && pPara->pDelSet->Count() )
306 			{
307                 // --> OD 2008-04-15 #refactorlists#
308                 ASSERT( !bKeepAttributes,
309                         "<lcl_RstAttr(..)> - certain attributes are kept, but not needed. -> please inform OD" );
310                 // <--
311 				SfxItemIter aIter( *pPara->pDelSet );
312 				pItem = aIter.FirstItem();
313 				while( sal_True )
314 				{
315                     // --> OD 2008-04-14 #refactorlists#
316                     //
317                     if ( ( pItem->Which() != RES_PAGEDESC &&
318                            pItem->Which() != RES_BREAK &&
319                            pItem->Which() != RES_PARATR_NUMRULE ) ||
320                          ( aSet.GetItemState( pItem->Which(), sal_False ) != SFX_ITEM_SET ) )
321                     {
322                         pNode->ResetAttr( pItem->Which() );
323                     }
324                     // <--
325 					if( aIter.IsAtEnd() )
326 						break;
327 					pItem = aIter.NextItem();
328 				}
329 			}
330 			else if( pPara->bResetAll )
331 				pNode->ResetAllAttr();
332 			else
333 				pNode->ResetAttr( RES_PARATR_BEGIN, POOLATTR_END - 1 );
334 		}
335 		else
336 			pNode->ResetAllAttr();
337 
338         // --> OD 2008-04-15 #refactorlists#
339         // only restore saved attributes, if needed
340         if ( bKeepAttributes && aSet.Count() )
341         // <--
342 		{
343             pNode->LockModify();
344 
345             pNode->SetAttr( aSet );
346 
347 			if( !bLocked )
348 				pNode->UnlockModify();
349 		}
350 	}
351 	return sal_True;
352 }
353 
354 void SwDoc::RstTxtAttrs(const SwPaM &rRg, sal_Bool bInclRefToxMark )
355 {
356 	SwHistory* pHst = 0;
357 	SwDataChanged aTmp( rRg, 0 );
358     if (GetIDocumentUndoRedo().DoesUndo())
359     {
360         SwUndoResetAttr* pUndo = new SwUndoResetAttr( rRg, RES_CHRFMT );
361         pHst = &pUndo->GetHistory();
362         GetIDocumentUndoRedo().AppendUndo(pUndo);
363     }
364 	const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End();
365 	ParaRstFmt aPara( pStt, pEnd, pHst );
366     aPara.bInclRefToxMark = ( bInclRefToxMark == sal_True );
367 	GetNodes().ForEach( pStt->nNode.GetIndex(), pEnd->nNode.GetIndex()+1,
368 						lcl_RstTxtAttr, &aPara );
369 	SetModified();
370 }
371 
372 void SwDoc::ResetAttrs( const SwPaM &rRg,
373                         sal_Bool bTxtAttr,
374                         const SvUShortsSort* pAttrs,
375                         // --> OD 2008-11-28 #b96644#
376                         const bool bSendDataChangedEvents )
377                         // <--
378 {
379 	SwPaM* pPam = (SwPaM*)&rRg;
380 	if( !bTxtAttr && pAttrs && pAttrs->Count() &&
381 		RES_TXTATR_END > (*pAttrs)[ 0 ] )
382 		bTxtAttr = sal_True;
383 
384 	if( !rRg.HasMark() )
385 	{
386 		SwTxtNode* pTxtNd = rRg.GetPoint()->nNode.GetNode().GetTxtNode();
387 		if( !pTxtNd )
388 			return ;
389 
390 		pPam = new SwPaM( *rRg.GetPoint() );
391 
392 		SwIndex& rSt = pPam->GetPoint()->nContent;
393 		sal_uInt16 nMkPos, nPtPos = rSt.GetIndex();
394 
395 		// JP 22.08.96: Sonderfall: steht der Crsr in einem URL-Attribut
396 		//				dann wird dessen Bereich genommen
397         SwTxtAttr const*const pURLAttr(
398             pTxtNd->GetTxtAttrAt(rSt.GetIndex(), RES_TXTATR_INETFMT));
399         if (pURLAttr && pURLAttr->GetINetFmt().GetValue().Len())
400 		{
401 			nMkPos = *pURLAttr->GetStart();
402 			nPtPos = *pURLAttr->End();
403 		}
404 		else
405 		{
406 			Boundary aBndry;
407 			if( pBreakIt->GetBreakIter().is() )
408 				aBndry = pBreakIt->GetBreakIter()->getWordBoundary(
409 							pTxtNd->GetTxt(), nPtPos,
410 							pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ),
411 							WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/,
412 							sal_True );
413 
414 			if( aBndry.startPos < nPtPos && nPtPos < aBndry.endPos )
415 			{
416 				nMkPos = (xub_StrLen)aBndry.startPos;
417 				nPtPos = (xub_StrLen)aBndry.endPos;
418 			}
419 			else
420 			{
421 				nPtPos = nMkPos = rSt.GetIndex();
422 				if( bTxtAttr )
423 					pTxtNd->DontExpandFmt( rSt, sal_True );
424 			}
425 		}
426 
427 		rSt = nMkPos;
428 		pPam->SetMark();
429 		pPam->GetPoint()->nContent = nPtPos;
430 	}
431 
432     // --> OD 2008-11-28 #i96644#
433 //    SwDataChanged aTmp( *pPam, 0 );
434     std::auto_ptr< SwDataChanged > pDataChanged;
435     if ( bSendDataChangedEvents )
436     {
437         pDataChanged.reset( new SwDataChanged( *pPam, 0 ) );
438     }
439     // <--
440 	SwHistory* pHst = 0;
441     if (GetIDocumentUndoRedo().DoesUndo())
442     {
443         SwUndoResetAttr* pUndo = new SwUndoResetAttr( rRg,
444             static_cast<sal_uInt16>(bTxtAttr ? RES_CONDTXTFMTCOLL : RES_TXTFMTCOLL ));
445 		if( pAttrs && pAttrs->Count() )
446         {
447             pUndo->SetAttrs( *pAttrs );
448         }
449         pHst = &pUndo->GetHistory();
450         GetIDocumentUndoRedo().AppendUndo(pUndo);
451     }
452 
453 	const SwPosition *pStt = pPam->Start(), *pEnd = pPam->End();
454 	ParaRstFmt aPara( pStt, pEnd, pHst );
455 
456     // mst: not including META here; it seems attrs with CH_TXTATR are omitted
457     sal_uInt16 __FAR_DATA aResetableSetRange[] = {
458         RES_FRMATR_BEGIN, RES_FRMATR_END-1,
459         RES_CHRATR_BEGIN, RES_CHRATR_END-1,
460         RES_PARATR_BEGIN, RES_PARATR_END-1,
461         // --> OD 2008-02-25 #refactorlists#
462         RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
463         // <--
464         RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
465         RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
466         RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY,
467         RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
468         RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
469         0
470     };
471 
472 	SfxItemSet aDelSet( GetAttrPool(), aResetableSetRange );
473 	if( pAttrs && pAttrs->Count() )
474 	{
475 		for( sal_uInt16 n = pAttrs->Count(); n; )
476 			if( POOLATTR_END > (*pAttrs)[ --n ] )
477 				aDelSet.Put( *GetDfltAttr( (*pAttrs)[ n ] ));
478 
479 		if( aDelSet.Count() )
480 			aPara.pDelSet = &aDelSet;
481 	}
482 
483 	sal_Bool bAdd = sal_True;
484 	SwNodeIndex aTmpStt( pStt->nNode );
485 	SwNodeIndex aTmpEnd( pEnd->nNode );
486 	if( pStt->nContent.GetIndex() )		// nur ein Teil
487 	{
488 		// dann spaeter aufsetzen und alle CharFmtAttr -> TxtFmtAttr
489 		SwTxtNode* pTNd = aTmpStt.GetNode().GetTxtNode();
490         if( pTNd && pTNd->HasSwAttrSet() && pTNd->GetpSwAttrSet()->Count() )
491 		{
492             if (pHst)
493             {
494                 SwRegHistory history(pTNd, *pTNd, pHst);
495                 pTNd->FmtToTxtAttr(pTNd);
496             }
497             else
498             {
499                 pTNd->FmtToTxtAttr(pTNd);
500             }
501 		}
502 
503 		aTmpStt++;
504 	}
505 	if( pEnd->nContent.GetIndex() == pEnd->nNode.GetNode().GetCntntNode()->Len() )
506 		// dann spaeter aufsetzen und alle CharFmtAttr -> TxtFmtAttr
507 		aTmpEnd++, bAdd = sal_False;
508 	else if( pStt->nNode != pEnd->nNode || !pStt->nContent.GetIndex() )
509 	{
510 		SwTxtNode* pTNd = aTmpEnd.GetNode().GetTxtNode();
511         if( pTNd && pTNd->HasSwAttrSet() && pTNd->GetpSwAttrSet()->Count() )
512 		{
513             if (pHst)
514             {
515                 SwRegHistory history(pTNd, *pTNd, pHst);
516                 pTNd->FmtToTxtAttr(pTNd);
517             }
518             else
519             {
520                 pTNd->FmtToTxtAttr(pTNd);
521             }
522 		}
523 	}
524 
525 	if( aTmpStt < aTmpEnd )
526 		GetNodes().ForEach( pStt->nNode, aTmpEnd, lcl_RstAttr, &aPara );
527 	else if( !rRg.HasMark() )
528 	{
529         aPara.bResetAll = false ;
530 		::lcl_RstAttr( &pStt->nNode.GetNode(), &aPara );
531         aPara.bResetAll = true ;
532 	}
533 
534 	if( bTxtAttr )
535 	{
536 		if( bAdd )
537 			aTmpEnd++;
538 		GetNodes().ForEach( pStt->nNode, aTmpEnd, lcl_RstTxtAttr, &aPara );
539 	}
540 
541 	if( pPam != &rRg )
542 		delete pPam;
543 
544 	SetModified();
545 }
546 
547 #define DELETECHARSETS if ( bDelete ) { delete pCharSet; delete pOtherSet; }
548 
549 // Einfuegen der Hints nach Inhaltsformen;
550 // wird in SwDoc::Insert(..., SwFmtHint &rHt) benutzt
551 
552 static bool lcl_InsAttr(
553     SwDoc *const pDoc,
554     const SwPaM &rRg,
555     const SfxItemSet& rChgSet,
556     const SetAttrMode nFlags,
557     SwUndoAttr *const pUndo,
558     //Modify here for #119405, by easyfan, 2012-05-24
559     const bool bExpandCharToPara=false)
560     //End of modification, by easyfan
561 {
562     // teil die Sets auf (fuer Selektion in Nodes)
563     const SfxItemSet* pCharSet = 0;
564     const SfxItemSet* pOtherSet = 0;
565     bool bDelete = false;
566     bool bCharAttr = false;
567     bool bOtherAttr = false;
568 
569     // Check, if we can work with rChgSet or if we have to create additional SfxItemSets
570     if ( 1 == rChgSet.Count() )
571     {
572         SfxItemIter aIter( rChgSet );
573         const SfxPoolItem* pItem = aIter.FirstItem();
574 
575         if (!IsInvalidItem(pItem))
576         {
577             const sal_uInt16 nWhich = pItem->Which();
578 
579             if ( isCHRATR(nWhich) ||
580                  (RES_TXTATR_CHARFMT == nWhich) ||
581                  (RES_TXTATR_INETFMT == nWhich) ||
582                  (RES_TXTATR_AUTOFMT == nWhich) ||
583                  (RES_TXTATR_UNKNOWN_CONTAINER == nWhich) )
584             {
585                 pCharSet  = &rChgSet;
586                 bCharAttr = true;
587             }
588 
589             if (    isPARATR(nWhich)
590                     || isPARATR_LIST(nWhich)
591                     || isFRMATR(nWhich)
592                     || isGRFATR(nWhich)
593                     || isUNKNOWNATR(nWhich)
594                     || isDrawingLayerAttribute(nWhich) ) //UUUU
595             {
596                 pOtherSet = &rChgSet;
597                 bOtherAttr = true;
598             }
599         }
600     }
601 
602     // Build new itemset if either
603     // - rChgSet.Count() > 1 or
604     // - The attribute in rChgSet does not belong to one of the above categories
605     if ( !bCharAttr && !bOtherAttr )
606     {
607         SfxItemSet* pTmpCharItemSet = new SfxItemSet( pDoc->GetAttrPool(),
608                                    RES_CHRATR_BEGIN, RES_CHRATR_END-1,
609                                    RES_TXTATR_AUTOFMT, RES_TXTATR_AUTOFMT,
610                                    RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
611                                    RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
612                RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
613                                    0 );
614 
615         SfxItemSet* pTmpOtherItemSet = new SfxItemSet( pDoc->GetAttrPool(),
616                                     RES_PARATR_BEGIN, RES_PARATR_END-1,
617                                     RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
618                                     RES_FRMATR_BEGIN, RES_FRMATR_END-1,
619                                     RES_GRFATR_BEGIN, RES_GRFATR_END-1,
620                                     RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
621 
622                                     //UUUU FillAttribute support
623                                     XATTR_FILL_FIRST, XATTR_FILL_LAST,
624 
625                                     0 );
626 
627         pTmpCharItemSet->Put( rChgSet );
628         pTmpOtherItemSet->Put( rChgSet );
629 
630         pCharSet = pTmpCharItemSet;
631         pOtherSet = pTmpOtherItemSet;
632 
633         bDelete = true;
634     }
635 
636     SwHistory* pHistory = pUndo ? &pUndo->GetHistory() : 0;
637     bool bRet = false;
638     const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End();
639     SwCntntNode* pNode = pStt->nNode.GetNode().GetCntntNode();
640 
641     if( pNode && pNode->IsTxtNode() )
642     {
643         // -> #i27615#
644         if (rRg.IsInFrontOfLabel())
645         {
646             SwTxtNode * pTxtNd = pNode->GetTxtNode();
647             SwNumRule * pNumRule = pTxtNd->GetNumRule();
648 
649             if ( !pNumRule )
650             {
651                 ASSERT( false,
652                         "<InsAttr(..)> - PaM in front of label, but text node has no numbering rule set. This is a serious defect, please inform OD." );
653                 DELETECHARSETS
654                 return false;
655             }
656 
657             SwNumFmt aNumFmt = pNumRule->Get(static_cast<sal_uInt16>(pTxtNd->GetActualListLevel()));
658             SwCharFmt * pCharFmt =
659                 pDoc->FindCharFmtByName(aNumFmt.GetCharFmtName());
660 
661             if (pCharFmt)
662             {
663                 if (pHistory)
664                     pHistory->Add(pCharFmt->GetAttrSet(), *pCharFmt);
665 
666                 if ( pCharSet )
667                     pCharFmt->SetFmtAttr(*pCharSet);
668             }
669 
670             DELETECHARSETS
671             return true;
672         }
673 
674         const SwIndex& rSt = pStt->nContent;
675 
676         // Attribute ohne Ende haben keinen Bereich
677         if ( !bCharAttr && !bOtherAttr )
678         {
679             SfxItemSet aTxtSet( pDoc->GetAttrPool(),
680                         RES_TXTATR_NOEND_BEGIN, RES_TXTATR_NOEND_END-1 );
681             aTxtSet.Put( rChgSet );
682             if( aTxtSet.Count() )
683             {
684                 SwRegHistory history( pNode, *pNode, pHistory );
685                 bRet = history.InsertItems(
686                     aTxtSet, rSt.GetIndex(), rSt.GetIndex(), nFlags ) || bRet;
687 
688                 if (bRet && (pDoc->IsRedlineOn() || (!pDoc->IsIgnoreRedline()
689                                 && pDoc->GetRedlineTbl().Count())))
690                 {
691                     SwPaM aPam( pStt->nNode, pStt->nContent.GetIndex()-1,
692                                 pStt->nNode, pStt->nContent.GetIndex() );
693 
694                     if( pUndo )
695                         pUndo->SaveRedlineData( aPam, sal_True );
696 
697                     if( pDoc->IsRedlineOn() )
698                         pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
699                     else
700                         pDoc->SplitRedline( aPam );
701                 }
702             }
703         }
704 
705         // TextAttribute mit Ende expandieren nie ihren Bereich
706         if ( !bCharAttr && !bOtherAttr )
707         {
708             // CharFmt wird gesondert behandelt !!!
709             // JP 22.08.96: URL-Attribute auch!!
710             // TEST_TEMP ToDo: AutoFmt!
711             SfxItemSet aTxtSet( pDoc->GetAttrPool(),
712                                 RES_TXTATR_REFMARK, RES_TXTATR_TOXMARK,
713                                 RES_TXTATR_META, RES_TXTATR_METAFIELD,
714                                 RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY,
715                                 RES_TXTATR_INPUTFIELD, RES_TXTATR_INPUTFIELD,
716                                 0 );
717 
718             aTxtSet.Put( rChgSet );
719             if( aTxtSet.Count() )
720             {
721                 sal_uInt16 nInsCnt = rSt.GetIndex();
722                 sal_uInt16 nEnd = pStt->nNode == pEnd->nNode
723                                 ? pEnd->nContent.GetIndex()
724                                 : pNode->Len();
725                 SwRegHistory history( pNode, *pNode, pHistory );
726                 bRet = history.InsertItems( aTxtSet, nInsCnt, nEnd, nFlags )
727                        || bRet;
728 
729                 if (bRet && (pDoc->IsRedlineOn() || (!pDoc->IsIgnoreRedline()
730                                 && pDoc->GetRedlineTbl().Count())))
731                 {
732                     // wurde Text-Inhalt eingefuegt? (RefMark/TOXMarks ohne Ende)
733                     sal_Bool bTxtIns = nInsCnt != rSt.GetIndex();
734                     // wurde Inhalt eingefuegt oder ueber die Selektion gesetzt?
735                     SwPaM aPam( pStt->nNode, bTxtIns ? nInsCnt + 1 : nEnd,
736                                 pStt->nNode, nInsCnt );
737                     if( pUndo )
738                         pUndo->SaveRedlineData( aPam, bTxtIns );
739 
740                     if( pDoc->IsRedlineOn() )
741                         pDoc->AppendRedline(
742                             new SwRedline(
743                                 bTxtIns ? nsRedlineType_t::REDLINE_INSERT : nsRedlineType_t::REDLINE_FORMAT, aPam ),
744                                 true);
745                     else if( bTxtIns )
746                         pDoc->SplitRedline( aPam );
747                 }
748             }
749         }
750     }
751 
752     // bei PageDesc's, die am Node gesetzt werden, muss immer das
753     // Auto-Flag gesetzt werden!!
754     if( pOtherSet && pOtherSet->Count() )
755     {
756         SwTableNode* pTblNd;
757         const SwFmtPageDesc* pDesc;
758         if( SFX_ITEM_SET == pOtherSet->GetItemState( RES_PAGEDESC,
759                         sal_False, (const SfxPoolItem**)&pDesc ))
760         {
761             if( pNode )
762             {
763                 // Auto-Flag setzen, nur in Vorlagen ist ohne Auto !
764                 SwFmtPageDesc aNew( *pDesc );
765                 // Bug 38479: AutoFlag wird jetzt in der WrtShell gesetzt
766                 // aNew.SetAuto();
767 
768                 // Tabellen kennen jetzt auch Umbrueche
769                 if( 0 == (nFlags & nsSetAttrMode::SETATTR_APICALL) &&
770                     0 != ( pTblNd = pNode->FindTableNode() ) )
771                 {
772                     SwTableNode* pCurTblNd = pTblNd;
773                     while ( 0 != ( pCurTblNd = pCurTblNd->StartOfSectionNode()->FindTableNode() ) )
774                         pTblNd = pCurTblNd;
775 
776                     // dann am Tabellen Format setzen
777                     SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt();
778                     SwRegHistory aRegH( pFmt, *pTblNd, pHistory );
779                     pFmt->SetFmtAttr( aNew );
780                     bRet = true;
781                 }
782                 else
783                 {
784                     SwRegHistory aRegH( pNode, *pNode, pHistory );
785                     bRet = pNode->SetAttr( aNew ) || bRet;
786                 }
787             }
788 
789             // bOtherAttr = true means that pOtherSet == rChgSet. In this case
790             // we know, that there is only one attribute in pOtherSet. We cannot
791             // perform the following operations, instead we return:
792             if ( bOtherAttr )
793                 return bRet;
794 
795             const_cast<SfxItemSet*>(pOtherSet)->ClearItem( RES_PAGEDESC );
796             if( !pOtherSet->Count() )
797             {
798                 DELETECHARSETS
799                 return bRet;
800             }
801         }
802 
803         // Tabellen kennen jetzt auch Umbrueche
804         const SvxFmtBreakItem* pBreak;
805         if( pNode && 0 == (nFlags & nsSetAttrMode::SETATTR_APICALL) &&
806             0 != (pTblNd = pNode->FindTableNode() ) &&
807             SFX_ITEM_SET == pOtherSet->GetItemState( RES_BREAK,
808                         sal_False, (const SfxPoolItem**)&pBreak ) )
809         {
810             SwTableNode* pCurTblNd = pTblNd;
811             while ( 0 != ( pCurTblNd = pCurTblNd->StartOfSectionNode()->FindTableNode() ) )
812                 pTblNd = pCurTblNd;
813 
814             // dann am Tabellen Format setzen
815             SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt();
816             SwRegHistory aRegH( pFmt, *pTblNd, pHistory );
817             pFmt->SetFmtAttr( *pBreak );
818             bRet = true;
819 
820             // bOtherAttr = true means that pOtherSet == rChgSet. In this case
821             // we know, that there is only one attribute in pOtherSet. We cannot
822             // perform the following operations, instead we return:
823             if ( bOtherAttr )
824                 return bRet;
825 
826             const_cast<SfxItemSet*>(pOtherSet)->ClearItem( RES_BREAK );
827             if( !pOtherSet->Count() )
828             {
829                 DELETECHARSETS
830                 return bRet;
831             }
832         }
833 
834         {
835             // wenns eine PoolNumRule ist, diese ggfs. anlegen
836             const SwNumRuleItem* pRule;
837             sal_uInt16 nPoolId;
838             if( SFX_ITEM_SET == pOtherSet->GetItemState( RES_PARATR_NUMRULE,
839                                 sal_False, (const SfxPoolItem**)&pRule ) &&
840                 !pDoc->FindNumRulePtr( pRule->GetValue() ) &&
841                 USHRT_MAX != (nPoolId = SwStyleNameMapper::GetPoolIdFromUIName ( pRule->GetValue(),
842                                 nsSwGetPoolIdFromName::GET_POOLID_NUMRULE )) )
843                 pDoc->GetNumRuleFromPool( nPoolId );
844         }
845 
846     }
847 
848     if( !rRg.HasMark() )		// kein Bereich
849     {
850         if( !pNode )
851         {
852             DELETECHARSETS
853             return bRet;
854         }
855 
856         if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
857         {
858             SwTxtNode* pTxtNd = static_cast<SwTxtNode*>(pNode);
859             const SwIndex& rSt = pStt->nContent;
860             sal_uInt16 nMkPos, nPtPos = rSt.GetIndex();
861             const String& rStr = pTxtNd->GetTxt();
862 
863             // JP 22.08.96: Sonderfall: steht der Crsr in einem URL-Attribut
864             //				dann wird dessen Bereich genommen
865             SwTxtAttr const*const pURLAttr(
866                 pTxtNd->GetTxtAttrAt(rSt.GetIndex(), RES_TXTATR_INETFMT));
867             if (pURLAttr && pURLAttr->GetINetFmt().GetValue().Len())
868             {
869                 nMkPos = *pURLAttr->GetStart();
870                 nPtPos = *pURLAttr->End();
871             }
872             else
873             {
874                 Boundary aBndry;
875                 if( pBreakIt->GetBreakIter().is() )
876                     aBndry = pBreakIt->GetBreakIter()->getWordBoundary(
877                                 pTxtNd->GetTxt(), nPtPos,
878                                 pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ),
879                                 WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/,
880                                 sal_True );
881 
882                 if( aBndry.startPos < nPtPos && nPtPos < aBndry.endPos )
883                 {
884                     nMkPos = (xub_StrLen)aBndry.startPos;
885                     nPtPos = (xub_StrLen)aBndry.endPos;
886                 }
887                 else
888                     nPtPos = nMkPos = rSt.GetIndex();
889             }
890 
891             // erstmal die zu ueberschreibenden Attribute aus dem
892             // SwpHintsArray entfernen, wenn die Selektion den gesamten
893             // Absatz umspannt. (Diese Attribute werden als FormatAttr.
894             // eingefuegt und verdraengen nie die TextAttr.!)
895             if( !(nFlags & nsSetAttrMode::SETATTR_DONTREPLACE ) &&
896                 pTxtNd->HasHints() && !nMkPos && nPtPos == rStr.Len() )
897             {
898                 SwIndex aSt( pTxtNd );
899                 if( pHistory )
900                 {
901                     // fuers Undo alle Attribute sichern
902                     SwRegHistory aRHst( *pTxtNd, pHistory );
903                     pTxtNd->GetpSwpHints()->Register( &aRHst );
904                     pTxtNd->RstTxtAttr( aSt, nPtPos, 0, pCharSet );
905                     if( pTxtNd->GetpSwpHints() )
906                         pTxtNd->GetpSwpHints()->DeRegister();
907                 }
908                 else
909                     pTxtNd->RstTxtAttr( aSt, nPtPos, 0, pCharSet );
910             }
911 
912             // the SwRegHistory inserts the attribute into the TxtNode!
913             SwRegHistory history( pNode, *pNode, pHistory );
914             bRet = history.InsertItems( *pCharSet, nMkPos, nPtPos, nFlags )
915                 || bRet;
916 
917             if( pDoc->IsRedlineOn() )
918             {
919                 SwPaM aPam( *pNode, nMkPos, *pNode, nPtPos );
920 
921                 if( pUndo )
922                     pUndo->SaveRedlineData( aPam, sal_False );
923                 pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_FORMAT, aPam ), true);
924             }
925         }
926         if( pOtherSet && pOtherSet->Count() )
927         {
928             SwRegHistory aRegH( pNode, *pNode, pHistory );
929 
930             //UUUU Need to check for unique item for DrawingLayer items of type NameOrIndex
931             // and evtl. correct that item to ensure unique names for that type. This call may
932             // modify/correct entries inside of the given SfxItemSet
933             SfxItemSet aTempLocalCopy(*pOtherSet);
934 
935             pDoc->CheckForUniqueItemForLineFillNameOrIndex(aTempLocalCopy);
936             bRet = pNode->SetAttr(aTempLocalCopy) || bRet;
937         }
938 
939         DELETECHARSETS
940         return bRet;
941     }
942 
943     if( pDoc->IsRedlineOn() && pCharSet && pCharSet->Count() )
944     {
945         if( pUndo )
946             pUndo->SaveRedlineData( rRg, sal_False );
947         pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_FORMAT, rRg ), true);
948     }
949 
950     /* jetzt wenn Bereich */
951     sal_uLong nNodes = 0;
952 
953     SwNodeIndex aSt( pDoc->GetNodes() );
954     SwNodeIndex aEnd( pDoc->GetNodes() );
955     SwIndex aCntEnd( pEnd->nContent );
956 
957     if( pNode )
958     {
959         sal_uInt16 nLen = pNode->Len();
960         if( pStt->nNode != pEnd->nNode )
961             aCntEnd.Assign( pNode, nLen );
962 
963         if( pStt->nContent.GetIndex() != 0 || aCntEnd.GetIndex() != nLen )
964         {
965             // the SwRegHistory inserts the attribute into the TxtNode!
966             if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
967             {
968                 SwRegHistory history( pNode, *pNode, pHistory );
969                 bRet = history.InsertItems(*pCharSet,
970                         pStt->nContent.GetIndex(), aCntEnd.GetIndex(), nFlags)
971                     || bRet;
972             }
973 
974             if( pOtherSet && pOtherSet->Count() )
975             {
976                 SwRegHistory aRegH( pNode, *pNode, pHistory );
977                 bRet = pNode->SetAttr( *pOtherSet ) || bRet;
978             }
979 
980             // lediglich Selektion in einem Node.
981             if( pStt->nNode == pEnd->nNode )
982             {
983             //Modify here for #119405, by easyfan, 2012-05-24
984             //The data parameter flag: bExpandCharToPara, comes from the data member of SwDoc,
985             //Which is set in SW MS word Binary filter WW8ImplRreader. With this flag on, means that
986             //current setting attribute set is a character range properties set and comes from a MS word
987             //binary file, And the setting range include a paragraph end position (0X0D);
988             //More specifications, as such property inside the character range properties set recorded in
989             //MS word binary file are dealed and inserted into data model (SwDoc) one by one, so we
990             //only dealing the scenario that the char properties set with 1 item inside;
991 
992                     if (bExpandCharToPara && pCharSet && pCharSet->Count() ==1 )
993             {
994                 SwTxtNode* pCurrentNd = pStt->nNode.GetNode().GetTxtNode();
995 
996                 if (pCurrentNd)
997                 {
998                     pCurrentNd->TryCharSetExpandToNum(*pCharSet);
999 
1000                 }
1001             }
1002             //End of modification, by easyfan
1003                 DELETECHARSETS
1004                 return bRet;
1005             }
1006             ++nNodes;
1007             aSt.Assign( pStt->nNode.GetNode(), +1 );
1008         }
1009         else
1010             aSt = pStt->nNode;
1011         aCntEnd = pEnd->nContent; // aEnd wurde veraendert !!
1012     }
1013     else
1014         aSt.Assign( pStt->nNode.GetNode(), +1 );
1015 
1016     // aSt zeigt jetzt auf den ersten vollen Node
1017 
1018     /*
1019      * die Selektion umfasst mehr als einen Node
1020      */
1021     if( pStt->nNode < pEnd->nNode )
1022     {
1023         pNode = pEnd->nNode.GetNode().GetCntntNode();
1024         if(pNode)
1025         {
1026             sal_uInt16 nLen = pNode->Len();
1027             if( aCntEnd.GetIndex() != nLen )
1028             {
1029                 // the SwRegHistory inserts the attribute into the TxtNode!
1030                 if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
1031                 {
1032                     SwRegHistory history( pNode, *pNode, pHistory );
1033                     history.InsertItems(*pCharSet,
1034                             0, aCntEnd.GetIndex(), nFlags);
1035                 }
1036 
1037                 if( pOtherSet && pOtherSet->Count() )
1038                 {
1039                     SwRegHistory aRegH( pNode, *pNode, pHistory );
1040                     pNode->SetAttr( *pOtherSet );
1041                 }
1042 
1043                 ++nNodes;
1044                 aEnd = pEnd->nNode;
1045             }
1046             else
1047                 aEnd.Assign( pEnd->nNode.GetNode(), +1 );
1048         }
1049         else
1050             aEnd = pEnd->nNode;
1051     }
1052     else
1053         aEnd.Assign( pEnd->nNode.GetNode(), +1 );
1054 
1055     // aEnd zeigt jetzt HINTER den letzten voll Node
1056 
1057     /* Bearbeitung der vollstaendig selektierten Nodes. */
1058 // alle Attribute aus dem Set zuruecksetzen !!
1059     if( pCharSet && pCharSet->Count() && !( nsSetAttrMode::SETATTR_DONTREPLACE & nFlags ) )
1060     {
1061 
1062         ParaRstFmt aPara( pStt, pEnd, pHistory, 0, pCharSet );
1063         pDoc->GetNodes().ForEach( aSt, aEnd, lcl_RstTxtAttr, &aPara );
1064     }
1065 
1066     sal_Bool bCreateSwpHints = pCharSet && (
1067         SFX_ITEM_SET == pCharSet->GetItemState( RES_TXTATR_CHARFMT, sal_False ) ||
1068         SFX_ITEM_SET == pCharSet->GetItemState( RES_TXTATR_INETFMT, sal_False ) );
1069 
1070     for(; aSt < aEnd; aSt++ )
1071     {
1072         pNode = aSt.GetNode().GetCntntNode();
1073         if( !pNode )
1074             continue;
1075 
1076         SwTxtNode* pTNd = pNode->GetTxtNode();
1077         if( pHistory )
1078         {
1079             SwRegHistory aRegH( pNode, *pNode, pHistory );
1080             SwpHints *pSwpHints;
1081 
1082             if( pTNd && pCharSet && pCharSet->Count() )
1083             {
1084                 pSwpHints = bCreateSwpHints ? &pTNd->GetOrCreateSwpHints()
1085                                             : pTNd->GetpSwpHints();
1086                 if( pSwpHints )
1087                     pSwpHints->Register( &aRegH );
1088 
1089                 pTNd->SetAttr( *pCharSet, 0, pTNd->GetTxt().Len(), nFlags );
1090                 if( pSwpHints )
1091                     pSwpHints->DeRegister();
1092             }
1093             if( pOtherSet && pOtherSet->Count() )
1094                 pNode->SetAttr( *pOtherSet );
1095         }
1096         else
1097         {
1098             if( pTNd && pCharSet && pCharSet->Count() )
1099                 pTNd->SetAttr( *pCharSet, 0, pTNd->GetTxt().Len(), nFlags );
1100             if( pOtherSet && pOtherSet->Count() )
1101                 pNode->SetAttr( *pOtherSet );
1102         }
1103         ++nNodes;
1104     }
1105 
1106     //The data parameter flag: bExpandCharToPara, comes from the data member of SwDoc,
1107     //Which is set in SW MS word Binary filter WW8ImplRreader. With this flag on, means that
1108     //current setting attribute set is a character range properties set and comes from a MS word
1109     //binary file, And the setting range include a paragraph end position (0X0D);
1110     //More specifications, as such property inside the character range properties set recorded in
1111     //MS word binary file are dealed and inserted into data model (SwDoc) one by one, so we
1112     //only dealing the scenario that the char properties set with 1 item inside;
1113     if (bExpandCharToPara && pCharSet && pCharSet->Count() ==1)
1114     {
1115         SwPosition aStartPos (*rRg.Start());
1116         SwPosition aEndPos (*rRg.End());
1117 
1118         if (aEndPos.nNode.GetNode().GetTxtNode() && aEndPos.nContent != aEndPos.nNode.GetNode().GetTxtNode()->Len())
1119             aEndPos.nNode--;
1120 
1121         for (;aStartPos<=aEndPos;aStartPos.nNode++)
1122         {
1123             SwTxtNode* pCurrentNd = aStartPos.nNode.GetNode().GetTxtNode();
1124 
1125             if (pCurrentNd)
1126             {
1127                 pCurrentNd->TryCharSetExpandToNum(*pCharSet);
1128 
1129             }
1130 
1131         }
1132     }
1133 
1134     DELETECHARSETS
1135     return (nNodes != 0) || bRet;
1136 }
1137 
1138 bool SwDoc::InsertPoolItem(
1139     const SwPaM &rRg,
1140     const SfxPoolItem &rHt,
1141     const SetAttrMode nFlags,
1142     const bool bExpandCharToPara)
1143 {
1144     SwDataChanged aTmp( rRg, 0 );
1145     SwUndoAttr* pUndoAttr = 0;
1146     if (GetIDocumentUndoRedo().DoesUndo())
1147     {
1148         GetIDocumentUndoRedo().ClearRedo();
1149         pUndoAttr = new SwUndoAttr( rRg, rHt, nFlags );
1150     }
1151 
1152     SfxItemSet aSet( GetAttrPool(), rHt.Which(), rHt.Which() );
1153     aSet.Put( rHt );
1154     const bool bRet = lcl_InsAttr( this, rRg, aSet, nFlags, pUndoAttr,bExpandCharToPara );
1155 
1156     if (GetIDocumentUndoRedo().DoesUndo())
1157     {
1158         GetIDocumentUndoRedo().AppendUndo( pUndoAttr );
1159     }
1160 
1161     if( bRet )
1162     {
1163         SetModified();
1164     }
1165     return bRet;
1166 }
1167 
1168 bool SwDoc::InsertItemSet ( const SwPaM &rRg, const SfxItemSet &rSet,
1169                             const SetAttrMode nFlags )
1170 {
1171 	SwDataChanged aTmp( rRg, 0 );
1172 	SwUndoAttr* pUndoAttr = 0;
1173     if (GetIDocumentUndoRedo().DoesUndo())
1174     {
1175         GetIDocumentUndoRedo().ClearRedo();
1176         pUndoAttr = new SwUndoAttr( rRg, rSet, nFlags );
1177 	}
1178 
1179     bool bRet = lcl_InsAttr( this, rRg, rSet, nFlags, pUndoAttr );
1180 
1181     if (GetIDocumentUndoRedo().DoesUndo())
1182     {
1183         GetIDocumentUndoRedo().AppendUndo( pUndoAttr );
1184     }
1185 
1186 	if( bRet )
1187 		SetModified();
1188 	return bRet;
1189 }
1190 
1191 
1192 	// Setze das Attribut im angegebenen Format. Ist Undo aktiv, wird
1193 	// das alte in die Undo-History aufgenommen
1194 void SwDoc::SetAttr( const SfxPoolItem& rAttr, SwFmt& rFmt )
1195 {
1196 	SfxItemSet aSet( GetAttrPool(), rAttr.Which(), rAttr.Which() );
1197 	aSet.Put( rAttr );
1198 	SetAttr( aSet, rFmt );
1199 }
1200 
1201 
1202 	// Setze das Attribut im angegebenen Format. Ist Undo aktiv, wird
1203 	// das alte in die Undo-History aufgenommen
1204 void SwDoc::SetAttr( const SfxItemSet& rSet, SwFmt& rFmt )
1205 {
1206     if (GetIDocumentUndoRedo().DoesUndo())
1207     {
1208         SwUndoFmtAttrHelper aTmp( rFmt );
1209         rFmt.SetFmtAttr( rSet );
1210         if ( aTmp.GetUndo() )
1211         {
1212             GetIDocumentUndoRedo().AppendUndo( aTmp.ReleaseUndo() );
1213         }
1214         else
1215         {
1216             GetIDocumentUndoRedo().ClearRedo();
1217         }
1218     }
1219     else
1220     {
1221         rFmt.SetFmtAttr( rSet );
1222     }
1223 	SetModified();
1224 }
1225 
1226 // --> OD 2008-02-12 #newlistlevelattrs#
1227 void SwDoc::ResetAttrAtFormat( const sal_uInt16 nWhichId,
1228                                SwFmt& rChangedFormat )
1229 {
1230     SwUndo *const pUndo = (GetIDocumentUndoRedo().DoesUndo())
1231         ?   new SwUndoFmtResetAttr( rChangedFormat, nWhichId )
1232         :   0;
1233 
1234     const sal_Bool bAttrReset = rChangedFormat.ResetFmtAttr( nWhichId );
1235 
1236     if ( bAttrReset )
1237     {
1238         if ( pUndo )
1239         {
1240             GetIDocumentUndoRedo().AppendUndo( pUndo );
1241         }
1242 
1243         SetModified();
1244     }
1245     else if ( pUndo )
1246         delete pUndo;
1247 }
1248 // <--
1249 
1250 int lcl_SetNewDefTabStops( SwTwips nOldWidth, SwTwips nNewWidth,
1251 								SvxTabStopItem& rChgTabStop )
1252 {
1253 	// dann aender bei allen TabStop die default's auf den neuen Wert
1254 	// !!! Achtung: hier wird immer auf dem PoolAttribut gearbeitet,
1255 	// 				damit nicht in allen Sets die gleiche Berechnung
1256 	//				auf dem gleichen TabStop (gepoolt!) vorgenommen
1257 	//				wird. Als Modify wird ein FmtChg verschickt.
1258 
1259 	sal_uInt16 nOldCnt = rChgTabStop.Count();
1260 	if( !nOldCnt || nOldWidth == nNewWidth )
1261 		return sal_False;
1262 
1263 	// suche den Anfang der Defaults
1264 	SvxTabStop* pTabs = ((SvxTabStop*)rChgTabStop.GetStart())
1265 						+ (nOldCnt-1);
1266 	sal_uInt16 n;
1267 
1268 	for( n = nOldCnt; n ; --n, --pTabs )
1269 		if( SVX_TAB_ADJUST_DEFAULT != pTabs->GetAdjustment() )
1270 			break;
1271 	++n;
1272 	if( n < nOldCnt )	// die DefTabStops loeschen
1273 		rChgTabStop.Remove( n, nOldCnt - n );
1274 	return sal_True;
1275 }
1276 
1277 // Setze das Attribut als neues default Attribut in diesem Dokument.
1278 // Ist Undo aktiv, wird das alte in die Undo-History aufgenommen
1279 void SwDoc::SetDefault( const SfxPoolItem& rAttr )
1280 {
1281 	SfxItemSet aSet( GetAttrPool(), rAttr.Which(), rAttr.Which() );
1282 	aSet.Put( rAttr );
1283 	SetDefault( aSet );
1284 }
1285 
1286 void SwDoc::SetDefault( const SfxItemSet& rSet )
1287 {
1288 	if( !rSet.Count() )
1289 		return;
1290 
1291 	SwModify aCallMod( 0 );
1292 	SwAttrSet aOld( GetAttrPool(), rSet.GetRanges() ),
1293 			aNew( GetAttrPool(), rSet.GetRanges() );
1294 	SfxItemIter aIter( rSet );
1295 	sal_uInt16 nWhich;
1296 	const SfxPoolItem* pItem = aIter.GetCurItem();
1297 	SfxItemPool* pSdrPool = GetAttrPool().GetSecondaryPool();
1298 	while( sal_True )
1299 	{
1300 		sal_Bool bCheckSdrDflt = sal_False;
1301 		nWhich = pItem->Which();
1302 		aOld.Put( GetAttrPool().GetDefaultItem( nWhich ) );
1303 		GetAttrPool().SetPoolDefaultItem( *pItem );
1304 		aNew.Put( GetAttrPool().GetDefaultItem( nWhich ) );
1305 
1306         if (isCHRATR(nWhich) || isTXTATR(nWhich))
1307         {
1308 			aCallMod.Add( pDfltTxtFmtColl );
1309 			aCallMod.Add( pDfltCharFmt );
1310 			bCheckSdrDflt = 0 != pSdrPool;
1311         }
1312         else if ( isPARATR(nWhich) ||
1313                   // --> OD 2008-02-25 #refactorlists#
1314                   isPARATR_LIST(nWhich) )
1315                   // <--
1316         {
1317 			aCallMod.Add( pDfltTxtFmtColl );
1318 			bCheckSdrDflt = 0 != pSdrPool;
1319         }
1320         else if (isGRFATR(nWhich))
1321         {
1322             aCallMod.Add( pDfltGrfFmtColl );
1323         }
1324         else if (isFRMATR(nWhich) || isDrawingLayerAttribute(nWhich) ) //UUUU
1325         {
1326 			aCallMod.Add( pDfltGrfFmtColl );
1327 			aCallMod.Add( pDfltTxtFmtColl );
1328 			aCallMod.Add( pDfltFrmFmt );
1329         }
1330         else if (isBOXATR(nWhich))
1331         {
1332             aCallMod.Add( pDfltFrmFmt );
1333         }
1334 
1335 		// copy also the defaults
1336 		if( bCheckSdrDflt )
1337 		{
1338 			sal_uInt16 nEdtWhich, nSlotId;
1339 			if( 0 != (nSlotId = GetAttrPool().GetSlotId( nWhich ) ) &&
1340 				nSlotId != nWhich &&
1341 				0 != (nEdtWhich = pSdrPool->GetWhich( nSlotId )) &&
1342 				nSlotId != nEdtWhich )
1343 			{
1344 				SfxPoolItem* pCpy = pItem->Clone();
1345 				pCpy->SetWhich( nEdtWhich );
1346 				pSdrPool->SetPoolDefaultItem( *pCpy );
1347 				delete pCpy;
1348 			}
1349 		}
1350 
1351 		if( aIter.IsAtEnd() )
1352 			break;
1353 		pItem = aIter.NextItem();
1354 	}
1355 
1356 	if( aNew.Count() && aCallMod.GetDepends() )
1357     {
1358         if (GetIDocumentUndoRedo().DoesUndo())
1359         {
1360             GetIDocumentUndoRedo().AppendUndo( new SwUndoDefaultAttr( aOld ) );
1361         }
1362 
1363 		const SfxPoolItem* pTmpItem;
1364 		if( ( SFX_ITEM_SET ==
1365                 aNew.GetItemState( RES_PARATR_TABSTOP, sal_False, &pTmpItem ) ) &&
1366 			((SvxTabStopItem*)pTmpItem)->Count() )
1367 		{
1368 			// TabStop-Aenderungen behandeln wir erstmal anders:
1369 			// dann aender bei allen TabStop die dafault's auf den neuen Wert
1370 			// !!! Achtung: hier wird immer auf dem PoolAttribut gearbeitet,
1371 			// 				damit nicht in allen Sets die gleiche Berechnung
1372 			//				auf dem gleichen TabStop (gepoolt!) vorgenommen
1373 			//				wird. Als Modify wird ein FmtChg verschickt.
1374 			SwTwips nNewWidth = (*(SvxTabStopItem*)pTmpItem)[ 0 ].GetTabPos(),
1375 					nOldWidth = ((SvxTabStopItem&)aOld.Get(RES_PARATR_TABSTOP))[ 0 ].GetTabPos();
1376 
1377 			int bChg = sal_False;
1378 			sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_PARATR_TABSTOP );
1379 			for( sal_uInt32 n = 0; n < nMaxItems; ++n )
1380 				if( 0 != (pTmpItem = GetAttrPool().GetItem2( RES_PARATR_TABSTOP, n ) ))
1381 					bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth,
1382 												*(SvxTabStopItem*)pTmpItem );
1383 
1384 			aNew.ClearItem( RES_PARATR_TABSTOP );
1385 			aOld.ClearItem( RES_PARATR_TABSTOP );
1386 			if( bChg )
1387 			{
1388 				SwFmtChg aChgFmt( pDfltCharFmt );
1389 				// dann sage mal den Frames bescheid
1390 				aCallMod.ModifyNotification( &aChgFmt, &aChgFmt );
1391 			}
1392 		}
1393 	}
1394 
1395 	if( aNew.Count() && aCallMod.GetDepends() )
1396 	{
1397 		SwAttrSetChg aChgOld( aOld, aOld );
1398 		SwAttrSetChg aChgNew( aNew, aNew );
1399 		aCallMod.ModifyNotification( &aChgOld, &aChgNew );		// alle veraenderten werden verschickt
1400 	}
1401 
1402 	// und die default-Formate wieder beim Object austragen
1403 	SwClient* pDep;
1404 	while( 0 != ( pDep = (SwClient*)aCallMod.GetDepends()) )
1405 		aCallMod.Remove( pDep );
1406 
1407 	SetModified();
1408 }
1409 
1410 	// Erfrage das Default Attribut in diesem Dokument.
1411 const SfxPoolItem& SwDoc::GetDefault( sal_uInt16 nFmtHint ) const
1412 {
1413 	return GetAttrPool().GetDefaultItem( nFmtHint );
1414 }
1415 
1416 /*
1417  * Loeschen der Formate
1418  */
1419 void SwDoc::DelCharFmt(sal_uInt16 nFmt, sal_Bool bBroadcast)
1420 {
1421     SwCharFmt * pDel = (*pCharFmtTbl)[nFmt];
1422 
1423     if (bBroadcast)
1424         BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_CHAR,
1425                                 SFX_STYLESHEET_ERASED);
1426 
1427     if (GetIDocumentUndoRedo().DoesUndo())
1428     {
1429         SwUndo * pUndo =
1430             new SwUndoCharFmtDelete(pDel, this);
1431 
1432         GetIDocumentUndoRedo().AppendUndo(pUndo);
1433     }
1434 
1435 	pCharFmtTbl->DeleteAndDestroy(nFmt);
1436 
1437 	SetModified();
1438 }
1439 
1440 void SwDoc::DelCharFmt( SwCharFmt *pFmt, sal_Bool bBroadcast )
1441 {
1442 	sal_uInt16 nFmt = pCharFmtTbl->GetPos( pFmt );
1443 	ASSERT( USHRT_MAX != nFmt, "Fmt not found," );
1444 
1445 	DelCharFmt( nFmt, bBroadcast );
1446 }
1447 
1448 void SwDoc::DelFrmFmt( SwFrmFmt *pFmt, sal_Bool bBroadcast )
1449 {
1450 	if( pFmt->ISA( SwTableBoxFmt ) || pFmt->ISA( SwTableLineFmt ))
1451 	{
1452 		ASSERT( !this, "Format steht nicht mehr im DocArray, "
1453 					   "kann per delete geloescht werden" );
1454 		delete pFmt;
1455 	}
1456 	else
1457 	{
1458 
1459 		//Das Format muss in einem der beiden Arrays stehen, in welchem
1460 		//werden wir schon merken.
1461 		sal_uInt16 nPos;
1462 		if ( USHRT_MAX != ( nPos = pFrmFmtTbl->GetPos( pFmt )) )
1463         {
1464             if (bBroadcast)
1465                 BroadcastStyleOperation(pFmt->GetName(),
1466                                         SFX_STYLE_FAMILY_FRAME,
1467                                         SFX_STYLESHEET_ERASED);
1468 
1469             if (GetIDocumentUndoRedo().DoesUndo())
1470             {
1471                 SwUndo * pUndo = new SwUndoFrmFmtDelete(pFmt, this);
1472 
1473                 GetIDocumentUndoRedo().AppendUndo(pUndo);
1474             }
1475 
1476 			pFrmFmtTbl->DeleteAndDestroy( nPos );
1477         }
1478 		else
1479 		{
1480 			nPos = GetSpzFrmFmts()->GetPos( pFmt );
1481 			ASSERT( nPos != USHRT_MAX, "FrmFmt not found." );
1482 			if( USHRT_MAX != nPos )
1483 				GetSpzFrmFmts()->DeleteAndDestroy( nPos );
1484 		}
1485 	}
1486 }
1487 
1488 void SwDoc::DelTblFrmFmt( SwTableFmt *pFmt )
1489 {
1490 	sal_uInt16 nPos = pTblFrmFmtTbl->GetPos( pFmt );
1491 	ASSERT( USHRT_MAX != nPos, "Fmt not found," );
1492 	pTblFrmFmtTbl->DeleteAndDestroy( nPos );
1493 }
1494 
1495 /*
1496  * Erzeugen der Formate
1497  */
1498 SwFlyFrmFmt *SwDoc::MakeFlyFrmFmt( const String &rFmtName,
1499 									SwFrmFmt *pDerivedFrom )
1500 {
1501 	SwFlyFrmFmt *pFmt = new SwFlyFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom );
1502 	GetSpzFrmFmts()->Insert(pFmt, GetSpzFrmFmts()->Count());
1503 	SetModified();
1504 	return pFmt;
1505 }
1506 
1507 SwDrawFrmFmt *SwDoc::MakeDrawFrmFmt( const String &rFmtName,
1508 									 SwFrmFmt *pDerivedFrom )
1509 {
1510 	SwDrawFrmFmt *pFmt = new SwDrawFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom);
1511 	GetSpzFrmFmts()->Insert(pFmt,GetSpzFrmFmts()->Count());
1512 	SetModified();
1513 	return pFmt;
1514 }
1515 
1516 
1517 sal_uInt16 SwDoc::GetTblFrmFmtCount(sal_Bool bUsed) const
1518 {
1519 	sal_uInt16 nCount = pTblFrmFmtTbl->Count();
1520 	if(bUsed)
1521 	{
1522         SwAutoFmtGetDocNode aGetHt( &GetNodes() );
1523 		for ( sal_uInt16 i = nCount; i; )
1524 		{
1525 			if((*pTblFrmFmtTbl)[--i]->GetInfo( aGetHt ))
1526 
1527 				--nCount;
1528 		}
1529 	}
1530 
1531 	return nCount;
1532 }
1533 
1534 
1535 SwFrmFmt& SwDoc::GetTblFrmFmt(sal_uInt16 nFmt, sal_Bool bUsed ) const
1536 {
1537 	sal_uInt16 nRemoved = 0;
1538 	if(bUsed)
1539 	{
1540         SwAutoFmtGetDocNode aGetHt( &GetNodes() );
1541 		for ( sal_uInt16 i = 0; i <= nFmt; i++ )
1542 		{
1543 			while ( (*pTblFrmFmtTbl)[ i + nRemoved]->GetInfo( aGetHt ))
1544 			{
1545 				nRemoved++;
1546 			}
1547 		}
1548 	}
1549 	return *((*pTblFrmFmtTbl)[nRemoved + nFmt]);
1550 }
1551 
1552 SwTableFmt* SwDoc::MakeTblFrmFmt( const String &rFmtName,
1553 									SwFrmFmt *pDerivedFrom )
1554 {
1555 	SwTableFmt* pFmt = new SwTableFmt( GetAttrPool(), rFmtName, pDerivedFrom );
1556 	pTblFrmFmtTbl->Insert( pFmt, pTblFrmFmtTbl->Count() );
1557 	SetModified();
1558 
1559 	return pFmt;
1560 }
1561 
1562 SwFrmFmt *SwDoc::MakeFrmFmt(const String &rFmtName,
1563 							SwFrmFmt *pDerivedFrom,
1564                             sal_Bool bBroadcast, sal_Bool bAuto)
1565 {
1566 
1567 	SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom );
1568 
1569     pFmt->SetAuto(bAuto);
1570 	pFrmFmtTbl->Insert( pFmt, pFrmFmtTbl->Count());
1571 	SetModified();
1572 
1573     if (bBroadcast)
1574     {
1575         BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_PARA,
1576                                 SFX_STYLESHEET_CREATED);
1577 
1578         if (GetIDocumentUndoRedo().DoesUndo())
1579         {
1580             SwUndo * pUndo = new SwUndoFrmFmtCreate(pFmt, pDerivedFrom, this);
1581 
1582             GetIDocumentUndoRedo().AppendUndo(pUndo);
1583         }
1584     }
1585 
1586 	return pFmt;
1587 }
1588 
1589 SwFmt *SwDoc::_MakeFrmFmt(const String &rFmtName,
1590 							SwFmt *pDerivedFrom,
1591                             sal_Bool bBroadcast, sal_Bool bAuto)
1592 {
1593     SwFrmFmt *pFrmFmt = dynamic_cast<SwFrmFmt*>(pDerivedFrom);
1594     pFrmFmt = MakeFrmFmt( rFmtName, pFrmFmt, bBroadcast, bAuto );
1595     return dynamic_cast<SwFmt*>(pFrmFmt);
1596 }
1597 
1598 
1599 // --> OD 2005-01-13 #i40550# - add parameter <bAuto> - not relevant
1600 SwCharFmt *SwDoc::MakeCharFmt( const String &rFmtName,
1601                                SwCharFmt *pDerivedFrom,
1602                                sal_Bool bBroadcast,
1603                                sal_Bool )
1604 // <--
1605 {
1606 	SwCharFmt *pFmt = new SwCharFmt( GetAttrPool(), rFmtName, pDerivedFrom );
1607     pCharFmtTbl->Insert( pFmt, pCharFmtTbl->Count() );
1608     pFmt->SetAuto( sal_False );
1609     SetModified();
1610 
1611     if (GetIDocumentUndoRedo().DoesUndo())
1612     {
1613         SwUndo * pUndo = new SwUndoCharFmtCreate(pFmt, pDerivedFrom, this);
1614 
1615         GetIDocumentUndoRedo().AppendUndo(pUndo);
1616     }
1617 
1618     if (bBroadcast)
1619     {
1620         BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_CHAR,
1621                                 SFX_STYLESHEET_CREATED);
1622     }
1623 
1624 	return pFmt;
1625 }
1626 
1627 SwFmt *SwDoc::_MakeCharFmt(const String &rFmtName,
1628 							SwFmt *pDerivedFrom,
1629                             sal_Bool bBroadcast, sal_Bool bAuto)
1630 {
1631     SwCharFmt *pCharFmt = dynamic_cast<SwCharFmt*>(pDerivedFrom);
1632     pCharFmt = MakeCharFmt( rFmtName, pCharFmt, bBroadcast, bAuto );
1633     return dynamic_cast<SwFmt*>(pCharFmt);
1634 }
1635 
1636 
1637 /*
1638  * Erzeugen der FormatCollections
1639  */
1640 // TXT
1641 // --> OD 2005-01-13 #i40550# - add parameter <bAuto> - not relevant
1642 SwTxtFmtColl* SwDoc::MakeTxtFmtColl( const String &rFmtName,
1643 									 SwTxtFmtColl *pDerivedFrom,
1644                                      sal_Bool bBroadcast,
1645                                      sal_Bool )
1646 // <--
1647 {
1648 	SwTxtFmtColl *pFmtColl = new SwTxtFmtColl( GetAttrPool(), rFmtName,
1649 												pDerivedFrom );
1650 	pTxtFmtCollTbl->Insert(pFmtColl, pTxtFmtCollTbl->Count());
1651 	pFmtColl->SetAuto( sal_False );
1652 	SetModified();
1653 
1654     if (GetIDocumentUndoRedo().DoesUndo())
1655     {
1656         SwUndo * pUndo = new SwUndoTxtFmtCollCreate(pFmtColl, pDerivedFrom,
1657                                                     this);
1658         GetIDocumentUndoRedo().AppendUndo(pUndo);
1659     }
1660 
1661     if (bBroadcast)
1662         BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_PARA,
1663                                 SFX_STYLESHEET_CREATED);
1664 
1665 	return pFmtColl;
1666 }
1667 
1668 SwFmt *SwDoc::_MakeTxtFmtColl(const String &rFmtName,
1669 							SwFmt *pDerivedFrom,
1670                             sal_Bool bBroadcast, sal_Bool bAuto)
1671 {
1672     SwTxtFmtColl *pTxtFmtColl = dynamic_cast<SwTxtFmtColl*>(pDerivedFrom);
1673     pTxtFmtColl = MakeTxtFmtColl( rFmtName, pTxtFmtColl, bBroadcast, bAuto );
1674     return dynamic_cast<SwFmt*>(pTxtFmtColl);
1675 }
1676 
1677 
1678 //FEATURE::CONDCOLL
1679 SwConditionTxtFmtColl* SwDoc::MakeCondTxtFmtColl( const String &rFmtName,
1680                                                   SwTxtFmtColl *pDerivedFrom,
1681                                                   sal_Bool bBroadcast)
1682 {
1683 	SwConditionTxtFmtColl*pFmtColl = new SwConditionTxtFmtColl( GetAttrPool(),
1684 													rFmtName, pDerivedFrom );
1685 	pTxtFmtCollTbl->Insert(pFmtColl, pTxtFmtCollTbl->Count());
1686 	pFmtColl->SetAuto( sal_False );
1687 	SetModified();
1688 
1689     if (bBroadcast)
1690         BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_PARA,
1691                                 SFX_STYLESHEET_CREATED);
1692 
1693 	return pFmtColl;
1694 }
1695 //FEATURE::CONDCOLL
1696 
1697 // GRF
1698 
1699 SwGrfFmtColl* SwDoc::MakeGrfFmtColl( const String &rFmtName,
1700 									 SwGrfFmtColl *pDerivedFrom )
1701 {
1702 	SwGrfFmtColl *pFmtColl = new SwGrfFmtColl( GetAttrPool(), rFmtName,
1703 												pDerivedFrom );
1704 	pGrfFmtCollTbl->Insert( pFmtColl, pGrfFmtCollTbl->Count() );
1705 	pFmtColl->SetAuto( sal_False );
1706 	SetModified();
1707 	return pFmtColl;
1708 }
1709 
1710 void SwDoc::DelTxtFmtColl(sal_uInt16 nFmtColl, sal_Bool bBroadcast)
1711 {
1712 	ASSERT( nFmtColl, "Remove fuer Coll 0." );
1713 
1714 	// Wer hat die zu loeschende als Next
1715 	SwTxtFmtColl *pDel = (*pTxtFmtCollTbl)[nFmtColl];
1716 	if( pDfltTxtFmtColl == pDel )
1717 		return;		// default nie loeschen !!
1718 
1719     if (bBroadcast)
1720         BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_PARA,
1721                                 SFX_STYLESHEET_ERASED);
1722 
1723     if (GetIDocumentUndoRedo().DoesUndo())
1724     {
1725         SwUndoTxtFmtCollDelete * pUndo =
1726             new SwUndoTxtFmtCollDelete(pDel, this);
1727 
1728         GetIDocumentUndoRedo().AppendUndo(pUndo);
1729     }
1730 
1731 	// Die FmtColl austragen
1732 	pTxtFmtCollTbl->Remove(nFmtColl);
1733 	// Next korrigieren
1734 	pTxtFmtCollTbl->ForEach( 1, pTxtFmtCollTbl->Count(),
1735 							&SetTxtFmtCollNext, pDel );
1736 	delete pDel;
1737 	SetModified();
1738 }
1739 
1740 void SwDoc::DelTxtFmtColl( SwTxtFmtColl *pColl, sal_Bool bBroadcast )
1741 {
1742 	sal_uInt16 nFmt = pTxtFmtCollTbl->GetPos( pColl );
1743 	ASSERT( USHRT_MAX != nFmt, "Collection not found," );
1744 	DelTxtFmtColl( nFmt, bBroadcast );
1745 }
1746 
1747 sal_Bool lcl_SetTxtFmtColl( const SwNodePtr& rpNode, void* pArgs )
1748 {
1749 	// ParaSetFmtColl * pPara = (ParaSetFmtColl*)pArgs;
1750 	SwCntntNode* pCNd = (SwCntntNode*)rpNode->GetTxtNode();
1751 	if( pCNd )
1752 	{
1753 		ParaRstFmt* pPara = (ParaRstFmt*)pArgs;
1754 
1755         SwTxtFmtColl* pFmt = static_cast<SwTxtFmtColl*>(pPara->pFmtColl);
1756 		if ( pPara->bReset )
1757         {
1758 
1759 			if( pFmt->GetAttrOutlineLevel() == 0 && pPara )
1760 				pPara->bKeepOutlineLevelAttr = true;
1761 
1762 			lcl_RstAttr( pCNd, pPara );
1763 
1764             // --> OD 2007-11-06 #i62675#
1765             // --> OD 2008-04-15 #refactorlists#
1766             // check, if paragraph style has changed
1767             if ( pPara->bResetListAttrs &&
1768                  pFmt != pCNd->GetFmtColl() &&
1769                  pFmt->GetItemState( RES_PARATR_NUMRULE ) == SFX_ITEM_SET )
1770             {
1771                 // --> OD 2009-09-07 #b6876367#
1772                 // Check, if the list style of the paragraph will change.
1773                 bool bChangeOfListStyleAtParagraph( true );
1774                 SwTxtNode* pTNd( dynamic_cast<SwTxtNode*>(pCNd) );
1775                 ASSERT( pTNd,
1776                         "<lcl_SetTxtFmtColl(..)> - text node expected -> crash" );
1777                 {
1778                     SwNumRule* pNumRuleAtParagraph( pTNd->GetNumRule() );
1779                     if ( pNumRuleAtParagraph )
1780                     {
1781                         const SwNumRuleItem& rNumRuleItemAtParagraphStyle =
1782                                                             pFmt->GetNumRule();
1783                         if ( rNumRuleItemAtParagraphStyle.GetValue() ==
1784                                                 pNumRuleAtParagraph->GetName() )
1785                         {
1786                             bChangeOfListStyleAtParagraph = false;
1787                         }
1788                     }
1789                 }
1790 
1791                 if ( bChangeOfListStyleAtParagraph )
1792                 {
1793                     // --> OD 2008-04-08 #refactorlists#
1794                     std::auto_ptr< SwRegHistory > pRegH;
1795                     if ( pPara->pHistory )
1796                     {
1797                         pRegH.reset( new SwRegHistory( pTNd, *pTNd, pPara->pHistory ) );
1798                     }
1799 
1800                     pCNd->ResetAttr( RES_PARATR_NUMRULE );
1801 
1802                     // reset all list attributes
1803                     pCNd->ResetAttr( RES_PARATR_LIST_LEVEL );
1804                     pCNd->ResetAttr( RES_PARATR_LIST_ISRESTART );
1805                     pCNd->ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
1806                     pCNd->ResetAttr( RES_PARATR_LIST_ISCOUNTED );
1807                     pCNd->ResetAttr( RES_PARATR_LIST_ID );
1808                 }
1809                 // <--
1810             }
1811             // <--
1812         }
1813 
1814         // erst in die History aufnehmen, damit ggfs. alte Daten
1815 		// gesichert werden koennen
1816 		if( pPara->pHistory )
1817 			pPara->pHistory->Add( pCNd->GetFmtColl(), pCNd->GetIndex(),
1818 									ND_TEXTNODE );
1819 
1820         pCNd->ChgFmtColl( pFmt );
1821 
1822 		pPara->nWhich++;
1823 	}
1824 	return sal_True;
1825 }
1826 
1827 sal_Bool SwDoc::SetTxtFmtColl( const SwPaM &rRg,
1828                            SwTxtFmtColl *pFmt,
1829                            bool bReset,
1830                            bool bResetListAttrs )
1831 {
1832 	SwDataChanged aTmp( rRg, 0 );
1833 	const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End();
1834 	SwHistory* pHst = 0;
1835 	sal_Bool bRet = sal_True;
1836 
1837     if (GetIDocumentUndoRedo().DoesUndo())
1838     {
1839         // --> OD 2008-04-15 #refactorlists#
1840         SwUndoFmtColl* pUndo = new SwUndoFmtColl( rRg, pFmt,
1841                                                   bReset,
1842                                                   bResetListAttrs );
1843         // <--
1844 		pHst = pUndo->GetHistory();
1845         GetIDocumentUndoRedo().AppendUndo(pUndo);
1846     }
1847 
1848     ParaRstFmt aPara( pStt, pEnd, pHst );
1849     aPara.pFmtColl = pFmt;
1850     aPara.bReset = bReset;
1851     // --> OD 2007-11-06 #i62675#
1852     aPara.bResetListAttrs = bResetListAttrs;
1853     // <--
1854 
1855     GetNodes().ForEach( pStt->nNode.GetIndex(), pEnd->nNode.GetIndex()+1,
1856                         lcl_SetTxtFmtColl, &aPara );
1857     if( !aPara.nWhich )
1858         bRet = sal_False;           // keinen gueltigen Node gefunden
1859 
1860 	if( bRet )
1861 		SetModified();
1862 	return bRet;
1863 }
1864 
1865 
1866 // ---- Kopiere die Formate in sich selbst (SwDoc) ----------------------
1867 
1868 SwFmt* SwDoc::CopyFmt( const SwFmt& rFmt,
1869 						const SvPtrarr& rFmtArr,
1870 						FNCopyFmt fnCopyFmt, const SwFmt& rDfltFmt )
1871 {
1872 	//  kein-Autoformat || default Format || Collection-Format
1873 	// dann suche danach.
1874 	if( !rFmt.IsAuto() || !rFmt.GetRegisteredIn() )
1875 		for( sal_uInt16 n = 0; n < rFmtArr.Count(); n++ )
1876 		{
1877 			// ist die Vorlage schon im Doc vorhanden ??
1878 			if( ((SwFmt*)rFmtArr[n])->GetName().Equals( rFmt.GetName() ))
1879 				return (SwFmt*)rFmtArr[n];
1880 		}
1881 
1882 	// suche erstmal nach dem "Parent"
1883 	SwFmt* pParent = (SwFmt*)&rDfltFmt;
1884 	if( rFmt.DerivedFrom() && pParent != rFmt.DerivedFrom() )
1885 		pParent = CopyFmt( *rFmt.DerivedFrom(), rFmtArr,
1886 								fnCopyFmt, rDfltFmt );
1887 
1888 	// erzeuge das Format und kopiere die Attribute
1889     // --> OD 2005-01-13 #i40550#
1890     SwFmt* pNewFmt = (this->*fnCopyFmt)( rFmt.GetName(), pParent, sal_False, sal_True );
1891     // <--
1892     pNewFmt->SetAuto( rFmt.IsAuto() );
1893 	pNewFmt->CopyAttrs( rFmt, sal_True );			// kopiere Attribute
1894 
1895 	pNewFmt->SetPoolFmtId( rFmt.GetPoolFmtId() );
1896 	pNewFmt->SetPoolHelpId( rFmt.GetPoolHelpId() );
1897 
1898 	// HelpFile-Id immer auf dflt setzen !!
1899 	pNewFmt->SetPoolHlpFileId( UCHAR_MAX );
1900 
1901 	return pNewFmt;
1902 }
1903 
1904 
1905 // ---- kopiere das Frame-Format --------
1906 SwFrmFmt* SwDoc::CopyFrmFmt( const SwFrmFmt& rFmt )
1907 {
1908 
1909     return (SwFrmFmt*)CopyFmt( rFmt, *GetFrmFmts(), &SwDoc::_MakeFrmFmt,
1910                                 *GetDfltFrmFmt() );
1911 }
1912 
1913 // ---- kopiere das Char-Format --------
1914 SwCharFmt* SwDoc::CopyCharFmt( const SwCharFmt& rFmt )
1915 {
1916 	return (SwCharFmt*)CopyFmt( rFmt, *GetCharFmts(),
1917 								&SwDoc::_MakeCharFmt,
1918 								*GetDfltCharFmt() );
1919 }
1920 
1921 
1922 // --- Kopiere TextNodes ----
1923 
1924 SwTxtFmtColl* SwDoc::CopyTxtColl( const SwTxtFmtColl& rColl )
1925 {
1926 	SwTxtFmtColl* pNewColl = FindTxtFmtCollByName( rColl.GetName() );
1927 	if( pNewColl )
1928 		return pNewColl;
1929 
1930 	// suche erstmal nach dem "Parent"
1931 	SwTxtFmtColl* pParent = pDfltTxtFmtColl;
1932 	if( pParent != rColl.DerivedFrom() )
1933 		pParent = CopyTxtColl( *(SwTxtFmtColl*)rColl.DerivedFrom() );
1934 
1935 
1936 //FEATURE::CONDCOLL
1937 	if( RES_CONDTXTFMTCOLL == rColl.Which() )
1938 	{
1939 		pNewColl = new SwConditionTxtFmtColl( GetAttrPool(), rColl.GetName(),
1940 												pParent);
1941 		pTxtFmtCollTbl->Insert( pNewColl, pTxtFmtCollTbl->Count() );
1942 		pNewColl->SetAuto( sal_False );
1943 		SetModified();
1944 
1945 		// Kopiere noch die Bedingungen
1946 		((SwConditionTxtFmtColl*)pNewColl)->SetConditions(
1947 							((SwConditionTxtFmtColl&)rColl).GetCondColls() );
1948 	}
1949 	else
1950 //FEATURE::CONDCOLL
1951 		pNewColl = MakeTxtFmtColl( rColl.GetName(), pParent );
1952 
1953 	// kopiere jetzt noch die Auto-Formate oder kopiere die Attribute
1954 	pNewColl->CopyAttrs( rColl, sal_True );
1955 
1956 	// setze noch den Outline-Level
1957     //if( NO_NUMBERING != rColl.GetOutlineLevel() )	//#outline level,zhaojianwei
1958 	//	pNewColl->SetOutlineLevel( rColl.GetOutlineLevel() );
1959     if(rColl.IsAssignedToListLevelOfOutlineStyle())
1960 		pNewColl->AssignToListLevelOfOutlineStyle(rColl.GetAssignedOutlineStyleLevel());//<-end,zhaojianwei
1961 	//<-end
1962 	pNewColl->SetPoolFmtId( rColl.GetPoolFmtId() );
1963 	pNewColl->SetPoolHelpId( rColl.GetPoolHelpId() );
1964 
1965 	// HelpFile-Id immer auf dflt setzen !!
1966 	pNewColl->SetPoolHlpFileId( UCHAR_MAX );
1967 
1968 	if( &rColl.GetNextTxtFmtColl() != &rColl )
1969 		pNewColl->SetNextTxtFmtColl( *CopyTxtColl( rColl.GetNextTxtFmtColl() ));
1970 
1971 	// ggfs. die NumRule erzeugen
1972 	if( this != rColl.GetDoc() )
1973 	{
1974 		const SfxPoolItem* pItem;
1975 		if( SFX_ITEM_SET == pNewColl->GetItemState( RES_PARATR_NUMRULE,
1976 			sal_False, &pItem ))
1977 		{
1978 			const SwNumRule* pRule;
1979 			const String& rName = ((SwNumRuleItem*)pItem)->GetValue();
1980 			if( rName.Len() &&
1981 				0 != ( pRule = rColl.GetDoc()->FindNumRulePtr( rName )) &&
1982 				!pRule->IsAutoRule() )
1983 			{
1984 				SwNumRule* pDestRule = FindNumRulePtr( rName );
1985 				if( pDestRule )
1986 					pDestRule->SetInvalidRule( sal_True );
1987 				else
1988 					MakeNumRule( rName, pRule );
1989 			}
1990 		}
1991 	}
1992 	return pNewColl;
1993 }
1994 
1995 // --- Kopiere GrafikNodes ----
1996 
1997 SwGrfFmtColl* SwDoc::CopyGrfColl( const SwGrfFmtColl& rColl )
1998 {
1999 	SwGrfFmtColl* pNewColl = FindGrfFmtCollByName( rColl.GetName() );
2000 	if( pNewColl )
2001 		return pNewColl;
2002 
2003 	// suche erstmal nach dem "Parent"
2004 	SwGrfFmtColl* pParent = pDfltGrfFmtColl;
2005 	if( pParent != rColl.DerivedFrom() )
2006 		pParent = CopyGrfColl( *(SwGrfFmtColl*)rColl.DerivedFrom() );
2007 
2008 	// falls nicht, so kopiere sie
2009 	pNewColl = MakeGrfFmtColl( rColl.GetName(), pParent );
2010 
2011 	// noch die Attribute kopieren
2012 	pNewColl->CopyAttrs( rColl );
2013 
2014 	pNewColl->SetPoolFmtId( rColl.GetPoolFmtId() );
2015 	pNewColl->SetPoolHelpId( rColl.GetPoolHelpId() );
2016 
2017 	// HelpFile-Id immer auf dflt setzen !!
2018 	pNewColl->SetPoolHlpFileId( UCHAR_MAX );
2019 
2020 	return pNewColl;
2021 }
2022 
2023 SwPageDesc* lcl_FindPageDesc( const SwPageDescs& rArr, const String& rName )
2024 {
2025 	for( sal_uInt16 n = rArr.Count(); n; )
2026 	{
2027 		SwPageDesc* pDesc = rArr[ --n ];
2028 		if( pDesc->GetName() == rName )
2029 			return pDesc;
2030 	}
2031 	return 0;
2032 }
2033 
2034 void SwDoc::CopyFmtArr( const SvPtrarr& rSourceArr,
2035 						SvPtrarr& rDestArr,
2036 						FNCopyFmt fnCopyFmt,
2037 						SwFmt& rDfltFmt )
2038 {
2039 	sal_uInt16 nSrc;
2040 	SwFmt* pSrc, *pDest;
2041 
2042 	// 1. Schritt alle Formate anlegen (das 0. ueberspringen - Default!)
2043 	for( nSrc = rSourceArr.Count(); nSrc > 1; )
2044 	{
2045 		pSrc = (SwFmt*)rSourceArr[ --nSrc ];
2046 		if( pSrc->IsDefault() || pSrc->IsAuto() )
2047 			continue;
2048 
2049 		if( 0 == FindFmtByName( rDestArr, pSrc->GetName() ) )
2050 		{
2051 			if( RES_CONDTXTFMTCOLL == pSrc->Which() )
2052                 MakeCondTxtFmtColl( pSrc->GetName(), (SwTxtFmtColl*)&rDfltFmt );
2053 			else
2054                 // --> OD 2005-01-13 #i40550#
2055                 (this->*fnCopyFmt)( pSrc->GetName(), &rDfltFmt, sal_False, sal_True );
2056                 // <--
2057 		}
2058 	}
2059 
2060 	// 2. Schritt alle Attribute kopieren, richtige Parents setzen
2061 	for( nSrc = rSourceArr.Count(); nSrc > 1; )
2062 	{
2063 		pSrc = (SwFmt*)rSourceArr[ --nSrc ];
2064 		if( pSrc->IsDefault() || pSrc->IsAuto() )
2065 			continue;
2066 
2067 		pDest = FindFmtByName( rDestArr, pSrc->GetName() );
2068 		pDest->SetAuto( sal_False );
2069 		pDest->DelDiffs( *pSrc );
2070 
2071         // #i94285#: existing <SwFmtPageDesc> instance, before copying attributes
2072         const SfxPoolItem* pItem;
2073         if( &GetAttrPool() != pSrc->GetAttrSet().GetPool() &&
2074             SFX_ITEM_SET == pSrc->GetAttrSet().GetItemState(
2075             RES_PAGEDESC, sal_False, &pItem ) &&
2076             ((SwFmtPageDesc*)pItem)->GetPageDesc() )
2077         {
2078             SwFmtPageDesc aPageDesc( *(SwFmtPageDesc*)pItem );
2079             const String& rNm = aPageDesc.GetPageDesc()->GetName();
2080             SwPageDesc* pPageDesc = ::lcl_FindPageDesc( aPageDescs, rNm );
2081             if( !pPageDesc )
2082             {
2083                 pPageDesc = aPageDescs[ MakePageDesc( rNm ) ];
2084             }
2085             aPageDesc.RegisterToPageDesc( *pPageDesc );
2086             SwAttrSet aTmpAttrSet( pSrc->GetAttrSet() );
2087             aTmpAttrSet.Put( aPageDesc );
2088             pDest->SetFmtAttr( aTmpAttrSet );
2089         }
2090         else
2091         {
2092             pDest->SetFmtAttr( pSrc->GetAttrSet() );
2093         }
2094 
2095 		pDest->SetPoolFmtId( pSrc->GetPoolFmtId() );
2096 		pDest->SetPoolHelpId( pSrc->GetPoolHelpId() );
2097 
2098 		// HelpFile-Id immer auf dflt setzen !!
2099 		pDest->SetPoolHlpFileId( UCHAR_MAX );
2100 
2101 		if( pSrc->DerivedFrom() )
2102 			pDest->SetDerivedFrom( FindFmtByName( rDestArr,
2103 										pSrc->DerivedFrom()->GetName() ) );
2104 		if( RES_TXTFMTCOLL == pSrc->Which() ||
2105 			RES_CONDTXTFMTCOLL == pSrc->Which() )
2106 		{
2107 			SwTxtFmtColl* pSrcColl = (SwTxtFmtColl*)pSrc,
2108 						* pDstColl = (SwTxtFmtColl*)pDest;
2109 			if( &pSrcColl->GetNextTxtFmtColl() != pSrcColl )
2110 				pDstColl->SetNextTxtFmtColl( *(SwTxtFmtColl*)FindFmtByName(
2111 					rDestArr, pSrcColl->GetNextTxtFmtColl().GetName() ) );
2112 
2113 			// setze noch den Outline-Level
2114 			//if( NO_NUMBERING != pSrcColl->GetOutlineLevel() )	//#outline level,zhaojianwei
2115 			//	pDstColl->SetOutlineLevel( pSrcColl->GetOutlineLevel() );
2116 			if(pSrcColl->IsAssignedToListLevelOfOutlineStyle())
2117 				pDstColl->AssignToListLevelOfOutlineStyle(pSrcColl->GetAssignedOutlineStyleLevel());//<-end,zhaojianwei
2118 			//<-end
2119 
2120 //FEATURE::CONDCOLL
2121 			if( RES_CONDTXTFMTCOLL == pSrc->Which() )
2122 				// Kopiere noch die Bedingungen
2123 				// aber erst die alten loeschen!
2124 				((SwConditionTxtFmtColl*)pDstColl)->SetConditions(
2125 							((SwConditionTxtFmtColl*)pSrc)->GetCondColls() );
2126 //FEATURE::CONDCOLL
2127 		}
2128 	}
2129 }
2130 
2131 void SwDoc::CopyPageDescHeaderFooterImpl( bool bCpyHeader,
2132 								const SwFrmFmt& rSrcFmt, SwFrmFmt& rDestFmt )
2133 {
2134 	// jetzt noch Header-/Footer-Attribute richtig behandeln
2135 	// Contenten Nodes Dokumentuebergreifend kopieren!
2136 	sal_uInt16 nAttr = static_cast<sal_uInt16>( bCpyHeader ? RES_HEADER : RES_FOOTER );
2137 	const SfxPoolItem* pItem;
2138 	if( SFX_ITEM_SET != rSrcFmt.GetAttrSet().GetItemState( nAttr, sal_False, &pItem ))
2139 		return ;
2140 
2141 	// Im Header steht noch der Verweis auf das Format aus dem
2142 	// anderen Document!!
2143 	SfxPoolItem* pNewItem = pItem->Clone();
2144 
2145 	SwFrmFmt* pOldFmt;
2146 	if( bCpyHeader )
2147 		 pOldFmt = ((SwFmtHeader*)pNewItem)->GetHeaderFmt();
2148 	else
2149 		 pOldFmt = ((SwFmtFooter*)pNewItem)->GetFooterFmt();
2150 
2151 	if( pOldFmt )
2152 	{
2153 		SwFrmFmt* pNewFmt = new SwFrmFmt( GetAttrPool(), "CpyDesc",
2154 											GetDfltFrmFmt() );
2155 		pNewFmt->CopyAttrs( *pOldFmt, sal_True );
2156 
2157 		if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState(
2158 			RES_CNTNT, sal_False, &pItem ))
2159 		{
2160 			SwFmtCntnt* pCntnt = (SwFmtCntnt*)pItem;
2161 			if( pCntnt->GetCntntIdx() )
2162 			{
2163 				SwNodeIndex aTmpIdx( GetNodes().GetEndOfAutotext() );
2164 				const SwNodes& rSrcNds = rSrcFmt.GetDoc()->GetNodes();
2165 				SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmpIdx,
2166 												bCpyHeader
2167 													? SwHeaderStartNode
2168 													: SwFooterStartNode );
2169 				const SwNode& rCSttNd = pCntnt->GetCntntIdx()->GetNode();
2170 				SwNodeRange aRg( rCSttNd, 0, *rCSttNd.EndOfSectionNode() );
2171 				aTmpIdx = *pSttNd->EndOfSectionNode();
2172 				rSrcNds._Copy( aRg, aTmpIdx );
2173 				aTmpIdx = *pSttNd;
2174                 rSrcFmt.GetDoc()->CopyFlyInFlyImpl( aRg, 0, aTmpIdx );
2175                 pNewFmt->SetFmtAttr( SwFmtCntnt( pSttNd ));
2176 			}
2177 			else
2178                 pNewFmt->ResetFmtAttr( RES_CNTNT );
2179 		}
2180 		if( bCpyHeader )
2181             ((SwFmtHeader*)pNewItem)->RegisterToFormat(*pNewFmt);
2182 		else
2183             ((SwFmtFooter*)pNewItem)->RegisterToFormat(*pNewFmt);
2184         rDestFmt.SetFmtAttr( *pNewItem );
2185 	}
2186 	delete pNewItem;
2187 }
2188 
2189 void SwDoc::CopyPageDesc( const SwPageDesc& rSrcDesc, SwPageDesc& rDstDesc,
2190 							sal_Bool bCopyPoolIds )
2191 {
2192 	sal_Bool bNotifyLayout = sal_False;
2193 	SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219
2194 
2195 	rDstDesc.SetLandscape( rSrcDesc.GetLandscape() );
2196 	rDstDesc.SetNumType( rSrcDesc.GetNumType() );
2197 	if( rDstDesc.ReadUseOn() != rSrcDesc.ReadUseOn() )
2198 	{
2199 		rDstDesc.WriteUseOn( rSrcDesc.ReadUseOn() );
2200 		bNotifyLayout = sal_True;
2201 	}
2202 
2203 	if( bCopyPoolIds )
2204 	{
2205 		rDstDesc.SetPoolFmtId( rSrcDesc.GetPoolFmtId() );
2206 		rDstDesc.SetPoolHelpId( rSrcDesc.GetPoolHelpId() );
2207 		// HelpFile-Id immer auf dflt setzen !!
2208 		rDstDesc.SetPoolHlpFileId( UCHAR_MAX );
2209 	}
2210 
2211 	if( rSrcDesc.GetFollow() != &rSrcDesc )
2212 	{
2213 		SwPageDesc* pFollow = ::lcl_FindPageDesc( aPageDescs,
2214 									rSrcDesc.GetFollow()->GetName() );
2215 		if( !pFollow )
2216 		{
2217 			// dann mal kopieren
2218 			sal_uInt16 nPos = MakePageDesc( rSrcDesc.GetFollow()->GetName() );
2219 			pFollow = aPageDescs[ nPos ];
2220 			CopyPageDesc( *rSrcDesc.GetFollow(), *pFollow );
2221 		}
2222 		rDstDesc.SetFollow( pFollow );
2223 		bNotifyLayout = sal_True;
2224 	}
2225 
2226 	// die Header/Footer-Attribute werden gesondert kopiert, die Content-
2227 	// Sections muessen vollstaendig mitgenommen werden!
2228 	{
2229 		SfxItemSet aAttrSet( rSrcDesc.GetMaster().GetAttrSet() );
2230 		aAttrSet.ClearItem( RES_HEADER );
2231 		aAttrSet.ClearItem( RES_FOOTER );
2232 
2233 		rDstDesc.GetMaster().DelDiffs( aAttrSet );
2234         rDstDesc.GetMaster().SetFmtAttr( aAttrSet );
2235 
2236 		aAttrSet.ClearItem();
2237 		aAttrSet.Put( rSrcDesc.GetLeft().GetAttrSet() );
2238 		aAttrSet.ClearItem( RES_HEADER );
2239 		aAttrSet.ClearItem( RES_FOOTER );
2240 
2241 		rDstDesc.GetLeft().DelDiffs( aAttrSet );
2242         rDstDesc.GetLeft().SetFmtAttr( aAttrSet );
2243 	}
2244 
2245 	CopyHeader( rSrcDesc.GetMaster(), rDstDesc.GetMaster() );
2246 	CopyFooter( rSrcDesc.GetMaster(), rDstDesc.GetMaster() );
2247 	if( !rDstDesc.IsHeaderShared() )
2248 		CopyHeader( rSrcDesc.GetLeft(), rDstDesc.GetLeft() );
2249 	else
2250         rDstDesc.GetLeft().SetFmtAttr( rDstDesc.GetMaster().GetHeader() );
2251 
2252 	if( !rDstDesc.IsFooterShared() )
2253 		CopyFooter( rSrcDesc.GetLeft(), rDstDesc.GetLeft() );
2254 	else
2255         rDstDesc.GetLeft().SetFmtAttr( rDstDesc.GetMaster().GetFooter() );
2256 
2257 	if( bNotifyLayout && pTmpRoot )
2258 	{
2259 		std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080225
2260 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs));//swmod 080226
2261 	}
2262 
2263 	//Wenn sich FussnotenInfo veraendert, so werden die Seiten
2264 	//angetriggert.
2265 	if( !(rDstDesc.GetFtnInfo() == rSrcDesc.GetFtnInfo()) )
2266 	{
2267 		rDstDesc.SetFtnInfo( rSrcDesc.GetFtnInfo() );
2268 		SwMsgPoolItem  aInfo( RES_PAGEDESC_FTNINFO );
2269 		{
2270             rDstDesc.GetMaster().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) );
2271 		}
2272 		{
2273             rDstDesc.GetLeft().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) );
2274 		}
2275 	}
2276 }
2277 
2278 void SwDoc::ReplaceStyles( SwDoc& rSource )
2279 {
2280     ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
2281 
2282 	CopyFmtArr( *rSource.pCharFmtTbl, *pCharFmtTbl,
2283 				&SwDoc::_MakeCharFmt, *pDfltCharFmt );
2284 	CopyFmtArr( *rSource.pFrmFmtTbl, *pFrmFmtTbl,
2285 				&SwDoc::_MakeFrmFmt, *pDfltFrmFmt );
2286 	CopyFmtArr( *rSource.pTxtFmtCollTbl, *pTxtFmtCollTbl,
2287 				&SwDoc::_MakeTxtFmtColl, *pDfltTxtFmtColl );
2288 
2289 	// und jetzt noch die Seiten-Vorlagen
2290 	sal_uInt16 nCnt = rSource.aPageDescs.Count();
2291 	if( nCnt )
2292 	{
2293 		// ein anderes Doc -> Numberformatter muessen gemergt werden
2294 		SwTblNumFmtMerge aTNFM( rSource, *this );
2295 
2296 		// 1. Schritt alle Formate anlegen (das 0. ueberspringen - Default!)
2297 		while( nCnt )
2298 		{
2299 			SwPageDesc *pSrc = rSource.aPageDescs[ --nCnt ];
2300 			if( 0 == ::lcl_FindPageDesc( aPageDescs, pSrc->GetName() ) )
2301 				MakePageDesc( pSrc->GetName() );
2302 		}
2303 
2304 		// 2. Schritt alle Attribute kopieren, richtige Parents setzen
2305 		for( nCnt = rSource.aPageDescs.Count(); nCnt; )
2306 		{
2307 			SwPageDesc *pSrc = rSource.aPageDescs[ --nCnt ];
2308 			CopyPageDesc( *pSrc, *::lcl_FindPageDesc( aPageDescs, pSrc->GetName() ));
2309 		}
2310 	}
2311 
2312 	//JP 08.04.99: und dann sind da noch die Numerierungs-Vorlagen
2313 	nCnt = rSource.GetNumRuleTbl().Count();
2314 	if( nCnt )
2315 	{
2316 		const SwNumRuleTbl& rArr = rSource.GetNumRuleTbl();
2317 		for( sal_uInt16 n = 0; n < nCnt; ++n )
2318 		{
2319 			const SwNumRule& rR = *rArr[ n ];
2320 			if( !rR.IsAutoRule() )
2321 			{
2322 				SwNumRule* pNew = FindNumRulePtr( rR.GetName());
2323 				if( pNew )
2324 					pNew->CopyNumRule( this, rR );
2325 				else
2326 					MakeNumRule( rR.GetName(), &rR );
2327 			}
2328 		}
2329 	}
2330 
2331     if (undoGuard.UndoWasEnabled())
2332     {
2333         // nodes array was modified!
2334         GetIDocumentUndoRedo().DelAllUndoObj();
2335     }
2336 
2337 	SetModified();
2338 }
2339 
2340 SwFmt* SwDoc::FindFmtByName( const SvPtrarr& rFmtArr,
2341 									const String& rName ) const
2342 {
2343 	SwFmt* pFnd = 0;
2344 	for( sal_uInt16 n = 0; n < rFmtArr.Count(); n++ )
2345 	{
2346 		// ist die Vorlage schon im Doc vorhanden ??
2347 		if( ((SwFmt*)rFmtArr[n])->GetName() == rName )
2348 		{
2349 			pFnd = (SwFmt*)rFmtArr[n];
2350 			break;
2351 		}
2352 	}
2353 	return pFnd;
2354 }
2355 
2356 void SwDoc::MoveLeftMargin( const SwPaM& rPam, sal_Bool bRight, sal_Bool bModulus )
2357 {
2358 	SwHistory* pHistory = 0;
2359     if (GetIDocumentUndoRedo().DoesUndo())
2360     {
2361 		SwUndoMoveLeftMargin* pUndo = new SwUndoMoveLeftMargin( rPam, bRight,
2362 																bModulus );
2363         pHistory = &pUndo->GetHistory();
2364         GetIDocumentUndoRedo().AppendUndo( pUndo );
2365     }
2366 
2367 	const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDefault( RES_PARATR_TABSTOP );
2368 	sal_uInt16 nDefDist = rTabItem.Count() ?
2369         static_cast<sal_uInt16>(rTabItem[0].GetTabPos()) : 1134;
2370 	const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End();
2371 	SwNodeIndex aIdx( rStt.nNode );
2372 	while( aIdx <= rEnd.nNode )
2373 	{
2374 		SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode();
2375 		if( pTNd )
2376 		{
2377             SvxLRSpaceItem aLS( (SvxLRSpaceItem&)pTNd->SwCntntNode::GetAttr( RES_LR_SPACE ) );
2378 
2379             // --> FME 2008-09-16 #i93873# See also lcl_MergeListLevelIndentAsLRSpaceItem in thints.cxx
2380             if ( pTNd->AreListLevelIndentsApplicable() )
2381             {
2382                 const SwNumRule* pRule = pTNd->GetNumRule();
2383                 if ( pRule )
2384                 {
2385                     const int nListLevel = pTNd->GetActualListLevel();
2386                     if ( nListLevel >= 0 )
2387                     {
2388                         const SwNumFmt& rFmt = pRule->Get(static_cast<sal_uInt16>(nListLevel));
2389                         if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
2390                         {
2391                             aLS.SetTxtLeft( rFmt.GetIndentAt() );
2392                             aLS.SetTxtFirstLineOfst( static_cast<short>(rFmt.GetFirstLineIndent()) );
2393                         }
2394                     }
2395                 }
2396             }
2397 
2398 			long nNext = aLS.GetTxtLeft();
2399 			if( bModulus )
2400 				nNext = ( nNext / nDefDist ) * nDefDist;
2401 
2402 			if( bRight )
2403 				nNext += nDefDist;
2404 			else
2405 				nNext -= nDefDist;
2406 
2407             aLS.SetTxtLeft( nNext );
2408 
2409 			SwRegHistory aRegH( pTNd, *pTNd, pHistory );
2410             pTNd->SetAttr( aLS );
2411 		}
2412 		aIdx++;
2413 	}
2414 	SetModified();
2415 }
2416 
2417 sal_Bool SwDoc::DontExpandFmt( const SwPosition& rPos, sal_Bool bFlag )
2418 {
2419 	sal_Bool bRet = sal_False;
2420 	SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
2421 	if( pTxtNd )
2422 	{
2423 		bRet = pTxtNd->DontExpandFmt( rPos.nContent, bFlag );
2424         if( bRet && GetIDocumentUndoRedo().DoesUndo() )
2425         {
2426             GetIDocumentUndoRedo().AppendUndo( new SwUndoDontExpandFmt(rPos) );
2427         }
2428     }
2429 	return bRet;
2430 }
2431 
2432 SwTableBoxFmt* SwDoc::MakeTableBoxFmt()
2433 {
2434 	SwTableBoxFmt* pFmt = new SwTableBoxFmt( GetAttrPool(), aEmptyStr,
2435 												pDfltFrmFmt );
2436 	SetModified();
2437 	return pFmt;
2438 }
2439 
2440 SwTableLineFmt* SwDoc::MakeTableLineFmt()
2441 {
2442 	SwTableLineFmt* pFmt = new SwTableLineFmt( GetAttrPool(), aEmptyStr,
2443 												pDfltFrmFmt );
2444 	SetModified();
2445 	return pFmt;
2446 }
2447 
2448 void SwDoc::_CreateNumberFormatter()
2449 {
2450 	RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722",  "SwDoc::_CreateNumberFormatter" );
2451 
2452 	ASSERT( !pNumberFormatter, "ist doch schon vorhanden" );
2453 
2454 
2455 	LanguageType eLang = LANGUAGE_SYSTEM; //System::GetLanguage();
2456 /*				((const SvxLanguageItem&)GetAttrPool().
2457 					GetDefaultItem( RES_CHRATR_LANGUAGE )).GetLanguage();
2458 */
2459 	Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
2460 	pNumberFormatter = new SvNumberFormatter( xMSF, eLang );
2461 	pNumberFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_FORMAT_INTL );
2462 	pNumberFormatter->SetYear2000(static_cast<sal_uInt16>(::utl::MiscCfg().GetYear2000()));
2463 
2464 }
2465 
2466 SwTblNumFmtMerge::SwTblNumFmtMerge( const SwDoc& rSrc, SwDoc& rDest )
2467 	: pNFmt( 0 )
2468 {
2469 	// ein anderes Doc -> Numberformatter muessen gemergt werden
2470 	SvNumberFormatter* pN;
2471 	if( &rSrc != &rDest && 0 != ( pN = ((SwDoc&)rSrc).GetNumberFormatter( sal_False ) ))
2472 		( pNFmt = rDest.GetNumberFormatter( sal_True ))->MergeFormatter( *pN );
2473 
2474 	if( &rSrc != &rDest )
2475 		((SwGetRefFieldType*)rSrc.GetSysFldType( RES_GETREFFLD ))->
2476 			MergeWithOtherDoc( rDest );
2477 }
2478 
2479 SwTblNumFmtMerge::~SwTblNumFmtMerge()
2480 {
2481 	if( pNFmt )
2482 		pNFmt->ClearMergeTable();
2483 }
2484 
2485 
2486 void SwDoc::SetTxtFmtCollByAutoFmt( const SwPosition& rPos, sal_uInt16 nPoolId,
2487 									const SfxItemSet* pSet )
2488 {
2489 	SwPaM aPam( rPos );
2490 	SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode();
2491 
2492 	if( mbIsAutoFmtRedline && pTNd )
2493 	{
2494 		// dann das Redline Object anlegen
2495 		const SwTxtFmtColl& rColl = *pTNd->GetTxtColl();
2496 		SwRedline* pRedl = new SwRedline( nsRedlineType_t::REDLINE_FMTCOLL, aPam );
2497 		pRedl->SetMark();
2498 
2499 		// interressant sind nur die Items, die vom Set NICHT wieder
2500 		// in den Node gesetzt werden. Also muss man die Differenz nehmen
2501 		SwRedlineExtraData_FmtColl aExtraData( rColl.GetName(),
2502 												rColl.GetPoolFmtId() );
2503         if( pSet && pTNd->HasSwAttrSet() )
2504 		{
2505 			SfxItemSet aTmp( *pTNd->GetpSwAttrSet() );
2506 			aTmp.Differentiate( *pSet );
2507 			// das Adjust Item behalten wir extra
2508 			const SfxPoolItem* pItem;
2509 			if( SFX_ITEM_SET == pTNd->GetpSwAttrSet()->GetItemState(
2510 					RES_PARATR_ADJUST, sal_False, &pItem ))
2511 				aTmp.Put( *pItem );
2512 			aExtraData.SetItemSet( aTmp );
2513 		}
2514 		pRedl->SetExtraData( &aExtraData );
2515 
2516 // !!!!!!!!! Undo fehlt noch !!!!!!!!!!!!!!!!!!
2517 		AppendRedline( pRedl, true );
2518 	}
2519 
2520 	SetTxtFmtColl( aPam, GetTxtCollFromPool( nPoolId ) );
2521 
2522 	if( pSet && pTNd && pSet->Count() )
2523 	{
2524 		aPam.SetMark();
2525 		aPam.GetMark()->nContent.Assign( pTNd, pTNd->GetTxt().Len() );
2526         InsertItemSet( aPam, *pSet, 0 );
2527     }
2528 }
2529 
2530 void SwDoc::SetFmtItemByAutoFmt( const SwPaM& rPam, const SfxItemSet& rSet )
2531 {
2532 	SwTxtNode* pTNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode();
2533 
2534 	RedlineMode_t eOld = GetRedlineMode();
2535 
2536 	if( mbIsAutoFmtRedline && pTNd )
2537 	{
2538 		// dann das Redline Object anlegen
2539 		SwRedline* pRedl = new SwRedline( nsRedlineType_t::REDLINE_FORMAT, rPam );
2540 		if( !pRedl->HasMark() )
2541 			pRedl->SetMark();
2542 
2543 		// interressant sind nur die Items, die vom Set NICHT wieder
2544 		// in den Node gesetzt werden. Also muss man die Differenz nehmen
2545 		SwRedlineExtraData_Format aExtraData( rSet );
2546 
2547 /*
2548         if( pSet && pTNd->HasSwAttrSet() )
2549 		{
2550 			SfxItemSet aTmp( *pTNd->GetpSwAttrSet() );
2551 			aTmp.Differentiate( *pSet );
2552 			// das Adjust Item behalten wir extra
2553 			const SfxPoolItem* pItem;
2554 			if( SFX_ITEM_SET == pTNd->GetpSwAttrSet()->GetItemState(
2555 					RES_PARATR_ADJUST, sal_False, &pItem ))
2556 				aTmp.Put( *pItem );
2557 			aExtraData.SetItemSet( aTmp );
2558 		}
2559 */
2560 		pRedl->SetExtraData( &aExtraData );
2561 
2562 // !!!!!!!!! Undo fehlt noch !!!!!!!!!!!!!!!!!!
2563 		AppendRedline( pRedl, true );
2564 
2565 		SetRedlineMode_intern( (RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
2566 	}
2567 
2568     InsertItemSet( rPam, rSet, nsSetAttrMode::SETATTR_DONTEXPAND );
2569 	SetRedlineMode_intern( eOld );
2570 }
2571 
2572 void SwDoc::ChgFmt(SwFmt & rFmt, const SfxItemSet & rSet)
2573 {
2574     if (GetIDocumentUndoRedo().DoesUndo())
2575     {
2576         // copying <rSet> to <aSet>
2577         SfxItemSet aSet(rSet);
2578         // remove from <aSet> all items, which are already set at the format
2579         aSet.Differentiate(rFmt.GetAttrSet());
2580         // <aSet> contains now all *new* items for the format
2581 
2582         // copying current format item set to <aOldSet>
2583         SfxItemSet aOldSet(rFmt.GetAttrSet());
2584         // insert new items into <aOldSet>
2585         aOldSet.Put(aSet);
2586         // invalidate all new items in <aOldSet> in order to clear these items,
2587         // if the undo action is triggered.
2588         {
2589             SfxItemIter aIter(aSet);
2590 
2591             const SfxPoolItem * pItem = aIter.FirstItem();
2592             while (pItem != NULL)
2593             {
2594                 aOldSet.InvalidateItem(pItem->Which());
2595 
2596                 pItem = aIter.NextItem();
2597             }
2598         }
2599 
2600         SwUndo * pUndo = new SwUndoFmtAttr(aOldSet, rFmt);
2601 
2602         GetIDocumentUndoRedo().AppendUndo(pUndo);
2603     }
2604 
2605     rFmt.SetFmtAttr(rSet);
2606 }
2607 
2608 void SwDoc::RenameFmt(SwFmt & rFmt, const String & sNewName,
2609                       sal_Bool bBroadcast)
2610 {
2611     SfxStyleFamily eFamily = SFX_STYLE_FAMILY_ALL;
2612 
2613     if (GetIDocumentUndoRedo().DoesUndo())
2614     {
2615         SwUndo * pUndo = NULL;
2616 
2617         switch (rFmt.Which())
2618         {
2619         case RES_CHRFMT:
2620             pUndo = new SwUndoRenameCharFmt(rFmt.GetName(), sNewName, this);
2621             eFamily = SFX_STYLE_FAMILY_PARA;
2622             break;
2623         case RES_TXTFMTCOLL:
2624             pUndo = new SwUndoRenameFmtColl(rFmt.GetName(), sNewName, this);
2625             eFamily = SFX_STYLE_FAMILY_CHAR;
2626             break;
2627         case RES_FRMFMT:
2628             pUndo = new SwUndoRenameFrmFmt(rFmt.GetName(), sNewName, this);
2629             eFamily = SFX_STYLE_FAMILY_FRAME;
2630             break;
2631 
2632         default:
2633             break;
2634         }
2635 
2636         if (pUndo)
2637         {
2638             GetIDocumentUndoRedo().AppendUndo(pUndo);
2639         }
2640     }
2641 
2642     rFmt.SetName(sNewName);
2643 
2644     if (bBroadcast)
2645         BroadcastStyleOperation(sNewName, eFamily, SFX_STYLESHEET_MODIFIED);
2646 }
2647 
2648 // --> OD 2006-09-27 #i69627#
2649 namespace docfunc
2650 {
2651     bool HasOutlineStyleToBeWrittenAsNormalListStyle( SwDoc& rDoc )
2652     {
2653         // If a parent paragraph style of one of the parargraph styles, which
2654         // are assigned to the list levels of the outline style, has a list style
2655         // set or inherits a list style from its parent style, the outline style
2656         // has to be written as a normal list style to the OpenDocument file
2657         // format or the OpenOffice.org file format.
2658         bool bRet( false );
2659 
2660         const SwTxtFmtColls* pTxtFmtColls( rDoc.GetTxtFmtColls() );
2661         if ( pTxtFmtColls )
2662         {
2663             const sal_uInt16 nCount = pTxtFmtColls->Count();
2664             for ( sal_uInt16 i = 0; i < nCount; ++i )
2665             {
2666                 SwTxtFmtColl* pTxtFmtColl = (*pTxtFmtColls)[i];
2667 
2668                 if ( pTxtFmtColl->IsDefault() ||
2669                    //  pTxtFmtColl->GetOutlineLevel() == NO_NUMBERING ) //#outline level,zhaojianwei
2670 					! pTxtFmtColl->IsAssignedToListLevelOfOutlineStyle() )	//<-end,zhaojianwei
2671                 {
2672                     continue;
2673                 }
2674 
2675                 const SwTxtFmtColl* pParentTxtFmtColl =
2676                    dynamic_cast<const SwTxtFmtColl*>( pTxtFmtColl->DerivedFrom());
2677                 if ( !pParentTxtFmtColl )
2678                     continue;
2679 
2680                 if ( SFX_ITEM_SET == pParentTxtFmtColl->GetItemState( RES_PARATR_NUMRULE ) )
2681                 {
2682                     // --> OD 2009-11-12 #i106218#
2683                     // consider that the outline style is set
2684                     const SwNumRuleItem& rDirectItem = pParentTxtFmtColl->GetNumRule();
2685                     if ( rDirectItem.GetValue() != rDoc.GetOutlineNumRule()->GetName() )
2686                     {
2687                         bRet = true;
2688                         break;
2689                     }
2690                     // <--
2691                 }
2692             }
2693 
2694         }
2695         return bRet;
2696     }
2697 }
2698 // <--
2699