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