xref: /trunk/main/sw/source/core/doc/docfmt.cxx (revision a5b190bfa3e1bed4623e2958a8877664a3b5506c)
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 
573         if (!IsInvalidItem(pItem))
574         {
575             const sal_uInt16 nWhich = pItem->Which();
576 
577             if ( isCHRATR(nWhich) ||
578                  (RES_TXTATR_CHARFMT == nWhich) ||
579                  (RES_TXTATR_INETFMT == nWhich) ||
580                  (RES_TXTATR_AUTOFMT == nWhich) ||
581                  (RES_TXTATR_UNKNOWN_CONTAINER == nWhich) )
582             {
583                 pCharSet  = &rChgSet;
584                 bCharAttr = true;
585             }
586 
587             if (    isPARATR(nWhich)
588                     || isPARATR_LIST(nWhich)
589                     || isFRMATR(nWhich)
590                     || isGRFATR(nWhich)
591                     || isUNKNOWNATR(nWhich) )
592             {
593                 pOtherSet = &rChgSet;
594                 bOtherAttr = true;
595             }
596         }
597     }
598 
599     // Build new itemset if either
600     // - rChgSet.Count() > 1 or
601     // - The attribute in rChgSet does not belong to one of the above categories
602     if ( !bCharAttr && !bOtherAttr )
603     {
604         SfxItemSet* pTmpCharItemSet = new SfxItemSet( pDoc->GetAttrPool(),
605                                    RES_CHRATR_BEGIN, RES_CHRATR_END-1,
606                                    RES_TXTATR_AUTOFMT, RES_TXTATR_AUTOFMT,
607                                    RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
608                                    RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
609                RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
610                                    0 );
611 
612         SfxItemSet* pTmpOtherItemSet = new SfxItemSet( pDoc->GetAttrPool(),
613                                     RES_PARATR_BEGIN, RES_PARATR_END-1,
614                                     // --> OD 2008-02-25 #refactorlists#
615                                     RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
616                                     // <--
617                                     RES_FRMATR_BEGIN, RES_FRMATR_END-1,
618                                     RES_GRFATR_BEGIN, RES_GRFATR_END-1,
619                                     RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
620                                     0 );
621 
622         pTmpCharItemSet->Put( rChgSet );
623         pTmpOtherItemSet->Put( rChgSet );
624 
625         pCharSet = pTmpCharItemSet;
626         pOtherSet = pTmpOtherItemSet;
627 
628         bDelete = true;
629     }
630 
631     SwHistory* pHistory = pUndo ? &pUndo->GetHistory() : 0;
632     bool bRet = false;
633     const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End();
634     SwCntntNode* pNode = pStt->nNode.GetNode().GetCntntNode();
635 
636     if( pNode && pNode->IsTxtNode() )
637     {
638         // -> #i27615#
639         if (rRg.IsInFrontOfLabel())
640         {
641             SwTxtNode * pTxtNd = pNode->GetTxtNode();
642             SwNumRule * pNumRule = pTxtNd->GetNumRule();
643 
644             // --> OD 2005-10-24 #126346# - make code robust:
645             if ( !pNumRule )
646             {
647                 ASSERT( false,
648                         "<InsAttr(..)> - PaM in front of label, but text node has no numbering rule set. This is a serious defect, please inform OD." );
649                 DELETECHARSETS
650                 return false;
651             }
652             // <--
653 
654             SwNumFmt aNumFmt = pNumRule->Get(static_cast<sal_uInt16>(pTxtNd->GetActualListLevel()));
655             SwCharFmt * pCharFmt =
656                 pDoc->FindCharFmtByName(aNumFmt.GetCharFmtName());
657 
658             if (pCharFmt)
659             {
660                 if (pHistory)
661                     pHistory->Add(pCharFmt->GetAttrSet(), *pCharFmt);
662 
663                 if ( pCharSet )
664                     pCharFmt->SetFmtAttr(*pCharSet);
665             }
666 
667             DELETECHARSETS
668             return true;
669         }
670         // <- #i27615#
671 
672         const SwIndex& rSt = pStt->nContent;
673 
674         // Attribute ohne Ende haben keinen Bereich
675         if ( !bCharAttr && !bOtherAttr )
676         {
677             SfxItemSet aTxtSet( pDoc->GetAttrPool(),
678                         RES_TXTATR_NOEND_BEGIN, RES_TXTATR_NOEND_END-1 );
679             aTxtSet.Put( rChgSet );
680             if( aTxtSet.Count() )
681             {
682                 SwRegHistory history( pNode, *pNode, pHistory );
683                 bRet = history.InsertItems(
684                     aTxtSet, rSt.GetIndex(), rSt.GetIndex(), nFlags ) || bRet;
685 
686                 if (bRet && (pDoc->IsRedlineOn() || (!pDoc->IsIgnoreRedline()
687                                 && pDoc->GetRedlineTbl().Count())))
688                 {
689                     SwPaM aPam( pStt->nNode, pStt->nContent.GetIndex()-1,
690                                 pStt->nNode, pStt->nContent.GetIndex() );
691 
692                     if( pUndo )
693                         pUndo->SaveRedlineData( aPam, sal_True );
694 
695                     if( pDoc->IsRedlineOn() )
696                         pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
697                     else
698                         pDoc->SplitRedline( aPam );
699                 }
700             }
701         }
702 
703         // TextAttribute mit Ende expandieren nie ihren Bereich
704         if ( !bCharAttr && !bOtherAttr )
705         {
706             // CharFmt wird gesondert behandelt !!!
707             // JP 22.08.96: URL-Attribute auch!!
708             // TEST_TEMP ToDo: AutoFmt!
709             SfxItemSet aTxtSet( pDoc->GetAttrPool(),
710                                 RES_TXTATR_REFMARK, RES_TXTATR_TOXMARK,
711                                 RES_TXTATR_META, RES_TXTATR_METAFIELD,
712                                 RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY,
713                                 0 );
714 
715             aTxtSet.Put( rChgSet );
716             if( aTxtSet.Count() )
717             {
718                 sal_uInt16 nInsCnt = rSt.GetIndex();
719                 sal_uInt16 nEnd = pStt->nNode == pEnd->nNode
720                                 ? pEnd->nContent.GetIndex()
721                                 : pNode->Len();
722                 SwRegHistory history( pNode, *pNode, pHistory );
723                 bRet = history.InsertItems( aTxtSet, nInsCnt, nEnd, nFlags )
724                     || bRet;
725 
726                 if (bRet && (pDoc->IsRedlineOn() || (!pDoc->IsIgnoreRedline()
727                                 && pDoc->GetRedlineTbl().Count())))
728                 {
729                     // wurde Text-Inhalt eingefuegt? (RefMark/TOXMarks ohne Ende)
730                     sal_Bool bTxtIns = nInsCnt != rSt.GetIndex();
731                     // wurde Inhalt eingefuegt oder ueber die Selektion gesetzt?
732                     SwPaM aPam( pStt->nNode, bTxtIns ? nInsCnt + 1 : nEnd,
733                                 pStt->nNode, nInsCnt );
734                     if( pUndo )
735                         pUndo->SaveRedlineData( aPam, bTxtIns );
736 
737                     if( pDoc->IsRedlineOn() )
738                         pDoc->AppendRedline( new SwRedline( bTxtIns
739                                 ? nsRedlineType_t::REDLINE_INSERT : nsRedlineType_t::REDLINE_FORMAT, aPam ), true);
740                     else if( bTxtIns )
741                         pDoc->SplitRedline( aPam );
742                 }
743             }
744         }
745     }
746 
747     // bei PageDesc's, die am Node gesetzt werden, muss immer das
748     // Auto-Flag gesetzt werden!!
749     if( pOtherSet && pOtherSet->Count() )
750     {
751         SwTableNode* pTblNd;
752         const SwFmtPageDesc* pDesc;
753         if( SFX_ITEM_SET == pOtherSet->GetItemState( RES_PAGEDESC,
754                         sal_False, (const SfxPoolItem**)&pDesc ))
755         {
756             if( pNode )
757             {
758                 // Auto-Flag setzen, nur in Vorlagen ist ohne Auto !
759                 SwFmtPageDesc aNew( *pDesc );
760                 // Bug 38479: AutoFlag wird jetzt in der WrtShell gesetzt
761                 // aNew.SetAuto();
762 
763                 // Tabellen kennen jetzt auch Umbrueche
764                 if( 0 == (nFlags & nsSetAttrMode::SETATTR_APICALL) &&
765                     0 != ( pTblNd = pNode->FindTableNode() ) )
766                 {
767                     SwTableNode* pCurTblNd = pTblNd;
768                     while ( 0 != ( pCurTblNd = pCurTblNd->StartOfSectionNode()->FindTableNode() ) )
769                         pTblNd = pCurTblNd;
770 
771                     // dann am Tabellen Format setzen
772                     SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt();
773                     SwRegHistory aRegH( pFmt, *pTblNd, pHistory );
774                     pFmt->SetFmtAttr( aNew );
775                     bRet = true;
776                 }
777                 else
778                 {
779                     SwRegHistory aRegH( pNode, *pNode, pHistory );
780                     bRet = pNode->SetAttr( aNew ) || bRet;
781                 }
782             }
783 
784             // bOtherAttr = true means that pOtherSet == rChgSet. In this case
785             // we know, that there is only one attribute in pOtherSet. We cannot
786             // perform the following operations, instead we return:
787             if ( bOtherAttr )
788                 return bRet;
789 
790             const_cast<SfxItemSet*>(pOtherSet)->ClearItem( RES_PAGEDESC );
791             if( !pOtherSet->Count() )
792             {
793                 DELETECHARSETS
794                 return bRet;
795             }
796         }
797 
798         // Tabellen kennen jetzt auch Umbrueche
799         const SvxFmtBreakItem* pBreak;
800         if( pNode && 0 == (nFlags & nsSetAttrMode::SETATTR_APICALL) &&
801             0 != (pTblNd = pNode->FindTableNode() ) &&
802             SFX_ITEM_SET == pOtherSet->GetItemState( RES_BREAK,
803                         sal_False, (const SfxPoolItem**)&pBreak ) )
804         {
805             SwTableNode* pCurTblNd = pTblNd;
806             while ( 0 != ( pCurTblNd = pCurTblNd->StartOfSectionNode()->FindTableNode() ) )
807                 pTblNd = pCurTblNd;
808 
809             // dann am Tabellen Format setzen
810             SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt();
811             SwRegHistory aRegH( pFmt, *pTblNd, pHistory );
812             pFmt->SetFmtAttr( *pBreak );
813             bRet = true;
814 
815             // bOtherAttr = true means that pOtherSet == rChgSet. In this case
816             // we know, that there is only one attribute in pOtherSet. We cannot
817             // perform the following operations, instead we return:
818             if ( bOtherAttr )
819                 return bRet;
820 
821             const_cast<SfxItemSet*>(pOtherSet)->ClearItem( RES_BREAK );
822             if( !pOtherSet->Count() )
823             {
824                 DELETECHARSETS
825                 return bRet;
826             }
827         }
828 
829         {
830             // wenns eine PoolNumRule ist, diese ggfs. anlegen
831             const SwNumRuleItem* pRule;
832             sal_uInt16 nPoolId;
833             if( SFX_ITEM_SET == pOtherSet->GetItemState( RES_PARATR_NUMRULE,
834                                 sal_False, (const SfxPoolItem**)&pRule ) &&
835                 !pDoc->FindNumRulePtr( pRule->GetValue() ) &&
836                 USHRT_MAX != (nPoolId = SwStyleNameMapper::GetPoolIdFromUIName ( pRule->GetValue(),
837                                 nsSwGetPoolIdFromName::GET_POOLID_NUMRULE )) )
838                 pDoc->GetNumRuleFromPool( nPoolId );
839         }
840 
841     }
842 
843     if( !rRg.HasMark() )        // kein Bereich
844     {
845         if( !pNode )
846         {
847             DELETECHARSETS
848             return bRet;
849         }
850 
851         if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
852         {
853             SwTxtNode* pTxtNd = static_cast<SwTxtNode*>(pNode);
854             const SwIndex& rSt = pStt->nContent;
855             sal_uInt16 nMkPos, nPtPos = rSt.GetIndex();
856             const String& rStr = pTxtNd->GetTxt();
857 
858             // JP 22.08.96: Sonderfall: steht der Crsr in einem URL-Attribut
859             //              dann wird dessen Bereich genommen
860             SwTxtAttr const*const pURLAttr(
861                 pTxtNd->GetTxtAttrAt(rSt.GetIndex(), RES_TXTATR_INETFMT));
862             if (pURLAttr && pURLAttr->GetINetFmt().GetValue().Len())
863             {
864                 nMkPos = *pURLAttr->GetStart();
865                 nPtPos = *pURLAttr->GetEnd();
866             }
867             else
868             {
869                 Boundary aBndry;
870                 if( pBreakIt->GetBreakIter().is() )
871                     aBndry = pBreakIt->GetBreakIter()->getWordBoundary(
872                                 pTxtNd->GetTxt(), nPtPos,
873                                 pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ),
874                                 WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/,
875                                 sal_True );
876 
877                 if( aBndry.startPos < nPtPos && nPtPos < aBndry.endPos )
878                 {
879                     nMkPos = (xub_StrLen)aBndry.startPos;
880                     nPtPos = (xub_StrLen)aBndry.endPos;
881                 }
882                 else
883                     nPtPos = nMkPos = rSt.GetIndex();
884             }
885 
886             // erstmal die zu ueberschreibenden Attribute aus dem
887             // SwpHintsArray entfernen, wenn die Selektion den gesamten
888             // Absatz umspannt. (Diese Attribute werden als FormatAttr.
889             // eingefuegt und verdraengen nie die TextAttr.!)
890             if( !(nFlags & nsSetAttrMode::SETATTR_DONTREPLACE ) &&
891                 pTxtNd->HasHints() && !nMkPos && nPtPos == rStr.Len() )
892             {
893                 SwIndex aSt( pTxtNd );
894                 if( pHistory )
895                 {
896                     // fuers Undo alle Attribute sichern
897                     SwRegHistory aRHst( *pTxtNd, pHistory );
898                     pTxtNd->GetpSwpHints()->Register( &aRHst );
899                     pTxtNd->RstAttr( aSt, nPtPos, 0, pCharSet );
900                     if( pTxtNd->GetpSwpHints() )
901                         pTxtNd->GetpSwpHints()->DeRegister();
902                 }
903                 else
904                     pTxtNd->RstAttr( aSt, nPtPos, 0, pCharSet );
905             }
906 
907             // the SwRegHistory inserts the attribute into the TxtNode!
908             SwRegHistory history( pNode, *pNode, pHistory );
909             bRet = history.InsertItems( *pCharSet, nMkPos, nPtPos, nFlags )
910                 || bRet;
911 
912             if( pDoc->IsRedlineOn() )
913             {
914                 SwPaM aPam( *pNode, nMkPos, *pNode, nPtPos );
915 
916                 if( pUndo )
917                     pUndo->SaveRedlineData( aPam, sal_False );
918                 pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_FORMAT, aPam ), true);
919             }
920         }
921         if( pOtherSet && pOtherSet->Count() )
922         {
923             SwRegHistory aRegH( pNode, *pNode, pHistory );
924             bRet = pNode->SetAttr( *pOtherSet ) || bRet;
925         }
926 
927         DELETECHARSETS
928         return bRet;
929     }
930 
931     if( pDoc->IsRedlineOn() && pCharSet && pCharSet->Count() )
932     {
933         if( pUndo )
934             pUndo->SaveRedlineData( rRg, sal_False );
935         pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_FORMAT, rRg ), true);
936     }
937 
938     /* jetzt wenn Bereich */
939     sal_uLong nNodes = 0;
940 
941     SwNodeIndex aSt( pDoc->GetNodes() );
942     SwNodeIndex aEnd( pDoc->GetNodes() );
943     SwIndex aCntEnd( pEnd->nContent );
944 
945     if( pNode )
946     {
947         sal_uInt16 nLen = pNode->Len();
948         if( pStt->nNode != pEnd->nNode )
949             aCntEnd.Assign( pNode, nLen );
950 
951         if( pStt->nContent.GetIndex() != 0 || aCntEnd.GetIndex() != nLen )
952         {
953             // the SwRegHistory inserts the attribute into the TxtNode!
954             if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
955             {
956                 SwRegHistory history( pNode, *pNode, pHistory );
957                 bRet = history.InsertItems(*pCharSet,
958                         pStt->nContent.GetIndex(), aCntEnd.GetIndex(), nFlags)
959                     || bRet;
960             }
961 
962             if( pOtherSet && pOtherSet->Count() )
963             {
964                 SwRegHistory aRegH( pNode, *pNode, pHistory );
965                 bRet = pNode->SetAttr( *pOtherSet ) || bRet;
966             }
967 
968             // lediglich Selektion in einem Node.
969             if( pStt->nNode == pEnd->nNode )
970             {
971                 DELETECHARSETS
972                 return bRet;
973             }
974             ++nNodes;
975             aSt.Assign( pStt->nNode.GetNode(), +1 );
976         }
977         else
978             aSt = pStt->nNode;
979         aCntEnd = pEnd->nContent; // aEnd wurde veraendert !!
980     }
981     else
982         aSt.Assign( pStt->nNode.GetNode(), +1 );
983 
984     // aSt zeigt jetzt auf den ersten vollen Node
985 
986     /*
987      * die Selektion umfasst mehr als einen Node
988      */
989     if( pStt->nNode < pEnd->nNode )
990     {
991         pNode = pEnd->nNode.GetNode().GetCntntNode();
992         if(pNode)
993         {
994             sal_uInt16 nLen = pNode->Len();
995             if( aCntEnd.GetIndex() != nLen )
996             {
997                 // the SwRegHistory inserts the attribute into the TxtNode!
998                 if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
999                 {
1000                     SwRegHistory history( pNode, *pNode, pHistory );
1001                     history.InsertItems(*pCharSet,
1002                             0, aCntEnd.GetIndex(), nFlags);
1003                 }
1004 
1005                 if( pOtherSet && pOtherSet->Count() )
1006                 {
1007                     SwRegHistory aRegH( pNode, *pNode, pHistory );
1008                     pNode->SetAttr( *pOtherSet );
1009                 }
1010 
1011                 ++nNodes;
1012                 aEnd = pEnd->nNode;
1013             }
1014             else
1015                 aEnd.Assign( pEnd->nNode.GetNode(), +1 );
1016         }
1017         else
1018             aEnd = pEnd->nNode;
1019     }
1020     else
1021         aEnd.Assign( pEnd->nNode.GetNode(), +1 );
1022 
1023     // aEnd zeigt jetzt HINTER den letzten voll Node
1024 
1025     /* Bearbeitung der vollstaendig selektierten Nodes. */
1026 // alle Attribute aus dem Set zuruecksetzen !!
1027     if( pCharSet && pCharSet->Count() && !( nsSetAttrMode::SETATTR_DONTREPLACE & nFlags ) )
1028     {
1029 
1030         ParaRstFmt aPara( pStt, pEnd, pHistory, 0, pCharSet );
1031         pDoc->GetNodes().ForEach( aSt, aEnd, lcl_RstTxtAttr, &aPara );
1032     }
1033 
1034     sal_Bool bCreateSwpHints = pCharSet && (
1035         SFX_ITEM_SET == pCharSet->GetItemState( RES_TXTATR_CHARFMT, sal_False ) ||
1036         SFX_ITEM_SET == pCharSet->GetItemState( RES_TXTATR_INETFMT, sal_False ) );
1037 
1038     for(; aSt < aEnd; aSt++ )
1039     {
1040         pNode = aSt.GetNode().GetCntntNode();
1041         if( !pNode )
1042             continue;
1043 
1044         SwTxtNode* pTNd = pNode->GetTxtNode();
1045         if( pHistory )
1046         {
1047             SwRegHistory aRegH( pNode, *pNode, pHistory );
1048             SwpHints *pSwpHints;
1049 
1050             if( pTNd && pCharSet && pCharSet->Count() )
1051             {
1052                 pSwpHints = bCreateSwpHints ? &pTNd->GetOrCreateSwpHints()
1053                                             : pTNd->GetpSwpHints();
1054                 if( pSwpHints )
1055                     pSwpHints->Register( &aRegH );
1056 
1057                 pTNd->SetAttr( *pCharSet, 0, pTNd->GetTxt().Len(), nFlags );
1058                 if( pSwpHints )
1059                     pSwpHints->DeRegister();
1060             }
1061             if( pOtherSet && pOtherSet->Count() )
1062                 pNode->SetAttr( *pOtherSet );
1063         }
1064         else
1065         {
1066             if( pTNd && pCharSet && pCharSet->Count() )
1067                 pTNd->SetAttr( *pCharSet, 0, pTNd->GetTxt().Len(), nFlags );
1068             if( pOtherSet && pOtherSet->Count() )
1069                 pNode->SetAttr( *pOtherSet );
1070         }
1071         ++nNodes;
1072     }
1073 
1074     DELETECHARSETS
1075     return (nNodes != 0) || bRet;
1076 }
1077 
1078 
1079 bool SwDoc::InsertPoolItem( const SwPaM &rRg, const SfxPoolItem &rHt,
1080                             const SetAttrMode nFlags )
1081 {
1082     SwDataChanged aTmp( rRg, 0 );
1083     SwUndoAttr* pUndoAttr = 0;
1084     if (GetIDocumentUndoRedo().DoesUndo())
1085     {
1086         GetIDocumentUndoRedo().ClearRedo();
1087         pUndoAttr = new SwUndoAttr( rRg, rHt, nFlags );
1088     }
1089 
1090     SfxItemSet aSet( GetAttrPool(), rHt.Which(), rHt.Which() );
1091     aSet.Put( rHt );
1092     bool bRet = lcl_InsAttr( this, rRg, aSet, nFlags, pUndoAttr );
1093 
1094     if (GetIDocumentUndoRedo().DoesUndo())
1095     {
1096         GetIDocumentUndoRedo().AppendUndo( pUndoAttr );
1097     }
1098 
1099     if( bRet )
1100         SetModified();
1101     return bRet;
1102 }
1103 
1104 bool SwDoc::InsertItemSet ( const SwPaM &rRg, const SfxItemSet &rSet,
1105                             const SetAttrMode nFlags )
1106 {
1107     SwDataChanged aTmp( rRg, 0 );
1108     SwUndoAttr* pUndoAttr = 0;
1109     if (GetIDocumentUndoRedo().DoesUndo())
1110     {
1111         GetIDocumentUndoRedo().ClearRedo();
1112         pUndoAttr = new SwUndoAttr( rRg, rSet, nFlags );
1113     }
1114 
1115     bool bRet = lcl_InsAttr( this, rRg, rSet, nFlags, pUndoAttr );
1116 
1117     if (GetIDocumentUndoRedo().DoesUndo())
1118     {
1119         GetIDocumentUndoRedo().AppendUndo( pUndoAttr );
1120     }
1121 
1122     if( bRet )
1123         SetModified();
1124     return bRet;
1125 }
1126 
1127 
1128     // Setze das Attribut im angegebenen Format. Ist Undo aktiv, wird
1129     // das alte in die Undo-History aufgenommen
1130 void SwDoc::SetAttr( const SfxPoolItem& rAttr, SwFmt& rFmt )
1131 {
1132     SfxItemSet aSet( GetAttrPool(), rAttr.Which(), rAttr.Which() );
1133     aSet.Put( rAttr );
1134     SetAttr( aSet, rFmt );
1135 }
1136 
1137 
1138     // Setze das Attribut im angegebenen Format. Ist Undo aktiv, wird
1139     // das alte in die Undo-History aufgenommen
1140 void SwDoc::SetAttr( const SfxItemSet& rSet, SwFmt& rFmt )
1141 {
1142     if (GetIDocumentUndoRedo().DoesUndo())
1143     {
1144         SwUndoFmtAttrHelper aTmp( rFmt );
1145         rFmt.SetFmtAttr( rSet );
1146         if ( aTmp.GetUndo() )
1147         {
1148             GetIDocumentUndoRedo().AppendUndo( aTmp.ReleaseUndo() );
1149         }
1150         else
1151         {
1152             GetIDocumentUndoRedo().ClearRedo();
1153         }
1154     }
1155     else
1156     {
1157         rFmt.SetFmtAttr( rSet );
1158     }
1159     SetModified();
1160 }
1161 
1162 // --> OD 2008-02-12 #newlistlevelattrs#
1163 void SwDoc::ResetAttrAtFormat( const sal_uInt16 nWhichId,
1164                                SwFmt& rChangedFormat )
1165 {
1166     SwUndo *const pUndo = (GetIDocumentUndoRedo().DoesUndo())
1167         ?   new SwUndoFmtResetAttr( rChangedFormat, nWhichId )
1168         :   0;
1169 
1170     const sal_Bool bAttrReset = rChangedFormat.ResetFmtAttr( nWhichId );
1171 
1172     if ( bAttrReset )
1173     {
1174         if ( pUndo )
1175         {
1176             GetIDocumentUndoRedo().AppendUndo( pUndo );
1177         }
1178 
1179         SetModified();
1180     }
1181     else if ( pUndo )
1182         delete pUndo;
1183 }
1184 // <--
1185 
1186 int lcl_SetNewDefTabStops( SwTwips nOldWidth, SwTwips nNewWidth,
1187                                 SvxTabStopItem& rChgTabStop )
1188 {
1189     // dann aender bei allen TabStop die default's auf den neuen Wert
1190     // !!! Achtung: hier wird immer auf dem PoolAttribut gearbeitet,
1191     //              damit nicht in allen Sets die gleiche Berechnung
1192     //              auf dem gleichen TabStop (gepoolt!) vorgenommen
1193     //              wird. Als Modify wird ein FmtChg verschickt.
1194 
1195     sal_uInt16 nOldCnt = rChgTabStop.Count();
1196     if( !nOldCnt || nOldWidth == nNewWidth )
1197         return sal_False;
1198 
1199     // suche den Anfang der Defaults
1200     SvxTabStop* pTabs = ((SvxTabStop*)rChgTabStop.GetStart())
1201                         + (nOldCnt-1);
1202     sal_uInt16 n;
1203 
1204     for( n = nOldCnt; n ; --n, --pTabs )
1205         if( SVX_TAB_ADJUST_DEFAULT != pTabs->GetAdjustment() )
1206             break;
1207     ++n;
1208     if( n < nOldCnt )   // die DefTabStops loeschen
1209         rChgTabStop.Remove( n, nOldCnt - n );
1210     return sal_True;
1211 }
1212 
1213 // Setze das Attribut als neues default Attribut in diesem Dokument.
1214 // Ist Undo aktiv, wird das alte in die Undo-History aufgenommen
1215 void SwDoc::SetDefault( const SfxPoolItem& rAttr )
1216 {
1217     SfxItemSet aSet( GetAttrPool(), rAttr.Which(), rAttr.Which() );
1218     aSet.Put( rAttr );
1219     SetDefault( aSet );
1220 }
1221 
1222 void SwDoc::SetDefault( const SfxItemSet& rSet )
1223 {
1224     if( !rSet.Count() )
1225         return;
1226 
1227     SwModify aCallMod( 0 );
1228     SwAttrSet aOld( GetAttrPool(), rSet.GetRanges() ),
1229             aNew( GetAttrPool(), rSet.GetRanges() );
1230     SfxItemIter aIter( rSet );
1231     sal_uInt16 nWhich;
1232     const SfxPoolItem* pItem = aIter.GetCurItem();
1233     SfxItemPool* pSdrPool = GetAttrPool().GetSecondaryPool();
1234     while( sal_True )
1235     {
1236         sal_Bool bCheckSdrDflt = sal_False;
1237         nWhich = pItem->Which();
1238         aOld.Put( GetAttrPool().GetDefaultItem( nWhich ) );
1239         GetAttrPool().SetPoolDefaultItem( *pItem );
1240         aNew.Put( GetAttrPool().GetDefaultItem( nWhich ) );
1241 
1242         if (isCHRATR(nWhich) || isTXTATR(nWhich))
1243         {
1244             aCallMod.Add( pDfltTxtFmtColl );
1245             aCallMod.Add( pDfltCharFmt );
1246             bCheckSdrDflt = 0 != pSdrPool;
1247         }
1248         else if ( isPARATR(nWhich) ||
1249                   // --> OD 2008-02-25 #refactorlists#
1250                   isPARATR_LIST(nWhich) )
1251                   // <--
1252         {
1253             aCallMod.Add( pDfltTxtFmtColl );
1254             bCheckSdrDflt = 0 != pSdrPool;
1255         }
1256         else if (isGRFATR(nWhich))
1257         {
1258             aCallMod.Add( pDfltGrfFmtColl );
1259         }
1260         else if (isFRMATR(nWhich))
1261         {
1262             aCallMod.Add( pDfltGrfFmtColl );
1263             aCallMod.Add( pDfltTxtFmtColl );
1264             aCallMod.Add( pDfltFrmFmt );
1265         }
1266         else if (isBOXATR(nWhich))
1267         {
1268             aCallMod.Add( pDfltFrmFmt );
1269         }
1270 
1271         // copy also the defaults
1272         if( bCheckSdrDflt )
1273         {
1274             sal_uInt16 nEdtWhich, nSlotId;
1275             if( 0 != (nSlotId = GetAttrPool().GetSlotId( nWhich ) ) &&
1276                 nSlotId != nWhich &&
1277                 0 != (nEdtWhich = pSdrPool->GetWhich( nSlotId )) &&
1278                 nSlotId != nEdtWhich )
1279             {
1280                 SfxPoolItem* pCpy = pItem->Clone();
1281                 pCpy->SetWhich( nEdtWhich );
1282                 pSdrPool->SetPoolDefaultItem( *pCpy );
1283                 delete pCpy;
1284             }
1285         }
1286 
1287         if( aIter.IsAtEnd() )
1288             break;
1289         pItem = aIter.NextItem();
1290     }
1291 
1292     if( aNew.Count() && aCallMod.GetDepends() )
1293     {
1294         if (GetIDocumentUndoRedo().DoesUndo())
1295         {
1296             GetIDocumentUndoRedo().AppendUndo( new SwUndoDefaultAttr( aOld ) );
1297         }
1298 
1299         const SfxPoolItem* pTmpItem;
1300         if( ( SFX_ITEM_SET ==
1301                 aNew.GetItemState( RES_PARATR_TABSTOP, sal_False, &pTmpItem ) ) &&
1302             ((SvxTabStopItem*)pTmpItem)->Count() )
1303         {
1304             // TabStop-Aenderungen behandeln wir erstmal anders:
1305             // dann aender bei allen TabStop die dafault's auf den neuen Wert
1306             // !!! Achtung: hier wird immer auf dem PoolAttribut gearbeitet,
1307             //              damit nicht in allen Sets die gleiche Berechnung
1308             //              auf dem gleichen TabStop (gepoolt!) vorgenommen
1309             //              wird. Als Modify wird ein FmtChg verschickt.
1310             SwTwips nNewWidth = (*(SvxTabStopItem*)pTmpItem)[ 0 ].GetTabPos(),
1311                     nOldWidth = ((SvxTabStopItem&)aOld.Get(RES_PARATR_TABSTOP))[ 0 ].GetTabPos();
1312 
1313             int bChg = sal_False;
1314             sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_PARATR_TABSTOP );
1315             for( sal_uInt32 n = 0; n < nMaxItems; ++n )
1316                 if( 0 != (pTmpItem = GetAttrPool().GetItem2( RES_PARATR_TABSTOP, n ) ))
1317                     bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth,
1318                                                 *(SvxTabStopItem*)pTmpItem );
1319 
1320             aNew.ClearItem( RES_PARATR_TABSTOP );
1321             aOld.ClearItem( RES_PARATR_TABSTOP );
1322             if( bChg )
1323             {
1324                 SwFmtChg aChgFmt( pDfltCharFmt );
1325                 // dann sage mal den Frames bescheid
1326                 aCallMod.ModifyNotification( &aChgFmt, &aChgFmt );
1327             }
1328         }
1329     }
1330 
1331     if( aNew.Count() && aCallMod.GetDepends() )
1332     {
1333         SwAttrSetChg aChgOld( aOld, aOld );
1334         SwAttrSetChg aChgNew( aNew, aNew );
1335         aCallMod.ModifyNotification( &aChgOld, &aChgNew );      // alle veraenderten werden verschickt
1336     }
1337 
1338     // und die default-Formate wieder beim Object austragen
1339     SwClient* pDep;
1340     while( 0 != ( pDep = (SwClient*)aCallMod.GetDepends()) )
1341         aCallMod.Remove( pDep );
1342 
1343     SetModified();
1344 }
1345 
1346     // Erfrage das Default Attribut in diesem Dokument.
1347 const SfxPoolItem& SwDoc::GetDefault( sal_uInt16 nFmtHint ) const
1348 {
1349     return GetAttrPool().GetDefaultItem( nFmtHint );
1350 }
1351 
1352 /*
1353  * Loeschen der Formate
1354  */
1355 void SwDoc::DelCharFmt(sal_uInt16 nFmt, sal_Bool bBroadcast)
1356 {
1357     SwCharFmt * pDel = (*pCharFmtTbl)[nFmt];
1358 
1359     if (bBroadcast)
1360         BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_CHAR,
1361                                 SFX_STYLESHEET_ERASED);
1362 
1363     if (GetIDocumentUndoRedo().DoesUndo())
1364     {
1365         SwUndo * pUndo =
1366             new SwUndoCharFmtDelete(pDel, this);
1367 
1368         GetIDocumentUndoRedo().AppendUndo(pUndo);
1369     }
1370 
1371     pCharFmtTbl->DeleteAndDestroy(nFmt);
1372 
1373     SetModified();
1374 }
1375 
1376 void SwDoc::DelCharFmt( SwCharFmt *pFmt, sal_Bool bBroadcast )
1377 {
1378     sal_uInt16 nFmt = pCharFmtTbl->GetPos( pFmt );
1379     ASSERT( USHRT_MAX != nFmt, "Fmt not found," );
1380 
1381     DelCharFmt( nFmt, bBroadcast );
1382 }
1383 
1384 void SwDoc::DelFrmFmt( SwFrmFmt *pFmt, sal_Bool bBroadcast )
1385 {
1386     if( pFmt->ISA( SwTableBoxFmt ) || pFmt->ISA( SwTableLineFmt ))
1387     {
1388         ASSERT( !this, "Format steht nicht mehr im DocArray, "
1389                        "kann per delete geloescht werden" );
1390         delete pFmt;
1391     }
1392     else
1393     {
1394 
1395         //Das Format muss in einem der beiden Arrays stehen, in welchem
1396         //werden wir schon merken.
1397         sal_uInt16 nPos;
1398         if ( USHRT_MAX != ( nPos = pFrmFmtTbl->GetPos( pFmt )) )
1399         {
1400             if (bBroadcast)
1401                 BroadcastStyleOperation(pFmt->GetName(),
1402                                         SFX_STYLE_FAMILY_FRAME,
1403                                         SFX_STYLESHEET_ERASED);
1404 
1405             if (GetIDocumentUndoRedo().DoesUndo())
1406             {
1407                 SwUndo * pUndo = new SwUndoFrmFmtDelete(pFmt, this);
1408 
1409                 GetIDocumentUndoRedo().AppendUndo(pUndo);
1410             }
1411 
1412             pFrmFmtTbl->DeleteAndDestroy( nPos );
1413         }
1414         else
1415         {
1416             nPos = GetSpzFrmFmts()->GetPos( pFmt );
1417             ASSERT( nPos != USHRT_MAX, "FrmFmt not found." );
1418             if( USHRT_MAX != nPos )
1419                 GetSpzFrmFmts()->DeleteAndDestroy( nPos );
1420         }
1421     }
1422 }
1423 
1424 void SwDoc::DelTblFrmFmt( SwTableFmt *pFmt )
1425 {
1426     sal_uInt16 nPos = pTblFrmFmtTbl->GetPos( pFmt );
1427     ASSERT( USHRT_MAX != nPos, "Fmt not found," );
1428     pTblFrmFmtTbl->DeleteAndDestroy( nPos );
1429 }
1430 
1431 /*
1432  * Erzeugen der Formate
1433  */
1434 SwFlyFrmFmt *SwDoc::MakeFlyFrmFmt( const String &rFmtName,
1435                                     SwFrmFmt *pDerivedFrom )
1436 {
1437     SwFlyFrmFmt *pFmt = new SwFlyFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom );
1438     GetSpzFrmFmts()->Insert(pFmt, GetSpzFrmFmts()->Count());
1439     SetModified();
1440     return pFmt;
1441 }
1442 
1443 SwDrawFrmFmt *SwDoc::MakeDrawFrmFmt( const String &rFmtName,
1444                                      SwFrmFmt *pDerivedFrom )
1445 {
1446     SwDrawFrmFmt *pFmt = new SwDrawFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom);
1447     GetSpzFrmFmts()->Insert(pFmt,GetSpzFrmFmts()->Count());
1448     SetModified();
1449     return pFmt;
1450 }
1451 
1452 
1453 sal_uInt16 SwDoc::GetTblFrmFmtCount(sal_Bool bUsed) const
1454 {
1455     sal_uInt16 nCount = pTblFrmFmtTbl->Count();
1456     if(bUsed)
1457     {
1458         SwAutoFmtGetDocNode aGetHt( &GetNodes() );
1459         for ( sal_uInt16 i = nCount; i; )
1460         {
1461             if((*pTblFrmFmtTbl)[--i]->GetInfo( aGetHt ))
1462 
1463                 --nCount;
1464         }
1465     }
1466 
1467     return nCount;
1468 }
1469 
1470 
1471 SwFrmFmt& SwDoc::GetTblFrmFmt(sal_uInt16 nFmt, sal_Bool bUsed ) const
1472 {
1473     sal_uInt16 nRemoved = 0;
1474     if(bUsed)
1475     {
1476         SwAutoFmtGetDocNode aGetHt( &GetNodes() );
1477         for ( sal_uInt16 i = 0; i <= nFmt; i++ )
1478         {
1479             while ( (*pTblFrmFmtTbl)[ i + nRemoved]->GetInfo( aGetHt ))
1480             {
1481                 nRemoved++;
1482             }
1483         }
1484     }
1485     return *((*pTblFrmFmtTbl)[nRemoved + nFmt]);
1486 }
1487 
1488 SwTableFmt* SwDoc::MakeTblFrmFmt( const String &rFmtName,
1489                                     SwFrmFmt *pDerivedFrom )
1490 {
1491     SwTableFmt* pFmt = new SwTableFmt( GetAttrPool(), rFmtName, pDerivedFrom );
1492     pTblFrmFmtTbl->Insert( pFmt, pTblFrmFmtTbl->Count() );
1493     SetModified();
1494 
1495     return pFmt;
1496 }
1497 
1498 SwFrmFmt *SwDoc::MakeFrmFmt(const String &rFmtName,
1499                             SwFrmFmt *pDerivedFrom,
1500                             sal_Bool bBroadcast, sal_Bool bAuto)
1501 {
1502 
1503     SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom );
1504 
1505     pFmt->SetAuto(bAuto);
1506     pFrmFmtTbl->Insert( pFmt, pFrmFmtTbl->Count());
1507     SetModified();
1508 
1509     if (bBroadcast)
1510     {
1511         BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_PARA,
1512                                 SFX_STYLESHEET_CREATED);
1513 
1514         if (GetIDocumentUndoRedo().DoesUndo())
1515         {
1516             SwUndo * pUndo = new SwUndoFrmFmtCreate(pFmt, pDerivedFrom, this);
1517 
1518             GetIDocumentUndoRedo().AppendUndo(pUndo);
1519         }
1520     }
1521 
1522     return pFmt;
1523 }
1524 
1525 SwFmt *SwDoc::_MakeFrmFmt(const String &rFmtName,
1526                             SwFmt *pDerivedFrom,
1527                             sal_Bool bBroadcast, sal_Bool bAuto)
1528 {
1529     SwFrmFmt *pFrmFmt = dynamic_cast<SwFrmFmt*>(pDerivedFrom);
1530     pFrmFmt = MakeFrmFmt( rFmtName, pFrmFmt, bBroadcast, bAuto );
1531     return dynamic_cast<SwFmt*>(pFrmFmt);
1532 }
1533 
1534 
1535 // --> OD 2005-01-13 #i40550# - add parameter <bAuto> - not relevant
1536 SwCharFmt *SwDoc::MakeCharFmt( const String &rFmtName,
1537                                SwCharFmt *pDerivedFrom,
1538                                sal_Bool bBroadcast,
1539                                sal_Bool )
1540 // <--
1541 {
1542     SwCharFmt *pFmt = new SwCharFmt( GetAttrPool(), rFmtName, pDerivedFrom );
1543     pCharFmtTbl->Insert( pFmt, pCharFmtTbl->Count() );
1544     pFmt->SetAuto( sal_False );
1545     SetModified();
1546 
1547     if (GetIDocumentUndoRedo().DoesUndo())
1548     {
1549         SwUndo * pUndo = new SwUndoCharFmtCreate(pFmt, pDerivedFrom, this);
1550 
1551         GetIDocumentUndoRedo().AppendUndo(pUndo);
1552     }
1553 
1554     if (bBroadcast)
1555     {
1556         BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_CHAR,
1557                                 SFX_STYLESHEET_CREATED);
1558     }
1559 
1560     return pFmt;
1561 }
1562 
1563 SwFmt *SwDoc::_MakeCharFmt(const String &rFmtName,
1564                             SwFmt *pDerivedFrom,
1565                             sal_Bool bBroadcast, sal_Bool bAuto)
1566 {
1567     SwCharFmt *pCharFmt = dynamic_cast<SwCharFmt*>(pDerivedFrom);
1568     pCharFmt = MakeCharFmt( rFmtName, pCharFmt, bBroadcast, bAuto );
1569     return dynamic_cast<SwFmt*>(pCharFmt);
1570 }
1571 
1572 
1573 /*
1574  * Erzeugen der FormatCollections
1575  */
1576 // TXT
1577 // --> OD 2005-01-13 #i40550# - add parameter <bAuto> - not relevant
1578 SwTxtFmtColl* SwDoc::MakeTxtFmtColl( const String &rFmtName,
1579                                      SwTxtFmtColl *pDerivedFrom,
1580                                      sal_Bool bBroadcast,
1581                                      sal_Bool )
1582 // <--
1583 {
1584     SwTxtFmtColl *pFmtColl = new SwTxtFmtColl( GetAttrPool(), rFmtName,
1585                                                 pDerivedFrom );
1586     pTxtFmtCollTbl->Insert(pFmtColl, pTxtFmtCollTbl->Count());
1587     pFmtColl->SetAuto( sal_False );
1588     SetModified();
1589 
1590     if (GetIDocumentUndoRedo().DoesUndo())
1591     {
1592         SwUndo * pUndo = new SwUndoTxtFmtCollCreate(pFmtColl, pDerivedFrom,
1593                                                     this);
1594         GetIDocumentUndoRedo().AppendUndo(pUndo);
1595     }
1596 
1597     if (bBroadcast)
1598         BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_PARA,
1599                                 SFX_STYLESHEET_CREATED);
1600 
1601     return pFmtColl;
1602 }
1603 
1604 SwFmt *SwDoc::_MakeTxtFmtColl(const String &rFmtName,
1605                             SwFmt *pDerivedFrom,
1606                             sal_Bool bBroadcast, sal_Bool bAuto)
1607 {
1608     SwTxtFmtColl *pTxtFmtColl = dynamic_cast<SwTxtFmtColl*>(pDerivedFrom);
1609     pTxtFmtColl = MakeTxtFmtColl( rFmtName, pTxtFmtColl, bBroadcast, bAuto );
1610     return dynamic_cast<SwFmt*>(pTxtFmtColl);
1611 }
1612 
1613 
1614 //FEATURE::CONDCOLL
1615 SwConditionTxtFmtColl* SwDoc::MakeCondTxtFmtColl( const String &rFmtName,
1616                                                   SwTxtFmtColl *pDerivedFrom,
1617                                                   sal_Bool bBroadcast)
1618 {
1619     SwConditionTxtFmtColl*pFmtColl = new SwConditionTxtFmtColl( GetAttrPool(),
1620                                                     rFmtName, pDerivedFrom );
1621     pTxtFmtCollTbl->Insert(pFmtColl, pTxtFmtCollTbl->Count());
1622     pFmtColl->SetAuto( sal_False );
1623     SetModified();
1624 
1625     if (bBroadcast)
1626         BroadcastStyleOperation(rFmtName, SFX_STYLE_FAMILY_PARA,
1627                                 SFX_STYLESHEET_CREATED);
1628 
1629     return pFmtColl;
1630 }
1631 //FEATURE::CONDCOLL
1632 
1633 // GRF
1634 
1635 SwGrfFmtColl* SwDoc::MakeGrfFmtColl( const String &rFmtName,
1636                                      SwGrfFmtColl *pDerivedFrom )
1637 {
1638     SwGrfFmtColl *pFmtColl = new SwGrfFmtColl( GetAttrPool(), rFmtName,
1639                                                 pDerivedFrom );
1640     pGrfFmtCollTbl->Insert( pFmtColl, pGrfFmtCollTbl->Count() );
1641     pFmtColl->SetAuto( sal_False );
1642     SetModified();
1643     return pFmtColl;
1644 }
1645 
1646 void SwDoc::DelTxtFmtColl(sal_uInt16 nFmtColl, sal_Bool bBroadcast)
1647 {
1648     ASSERT( nFmtColl, "Remove fuer Coll 0." );
1649 
1650     // Wer hat die zu loeschende als Next
1651     SwTxtFmtColl *pDel = (*pTxtFmtCollTbl)[nFmtColl];
1652     if( pDfltTxtFmtColl == pDel )
1653         return;     // default nie loeschen !!
1654 
1655     if (bBroadcast)
1656         BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_PARA,
1657                                 SFX_STYLESHEET_ERASED);
1658 
1659     if (GetIDocumentUndoRedo().DoesUndo())
1660     {
1661         SwUndoTxtFmtCollDelete * pUndo =
1662             new SwUndoTxtFmtCollDelete(pDel, this);
1663 
1664         GetIDocumentUndoRedo().AppendUndo(pUndo);
1665     }
1666 
1667     // Die FmtColl austragen
1668     pTxtFmtCollTbl->Remove(nFmtColl);
1669     // Next korrigieren
1670     pTxtFmtCollTbl->ForEach( 1, pTxtFmtCollTbl->Count(),
1671                             &SetTxtFmtCollNext, pDel );
1672     delete pDel;
1673     SetModified();
1674 }
1675 
1676 void SwDoc::DelTxtFmtColl( SwTxtFmtColl *pColl, sal_Bool bBroadcast )
1677 {
1678     sal_uInt16 nFmt = pTxtFmtCollTbl->GetPos( pColl );
1679     ASSERT( USHRT_MAX != nFmt, "Collection not found," );
1680     DelTxtFmtColl( nFmt, bBroadcast );
1681 }
1682 
1683 sal_Bool lcl_SetTxtFmtColl( const SwNodePtr& rpNode, void* pArgs )
1684 {
1685     // ParaSetFmtColl * pPara = (ParaSetFmtColl*)pArgs;
1686     SwCntntNode* pCNd = (SwCntntNode*)rpNode->GetTxtNode();
1687     if( pCNd )
1688     {
1689         ParaRstFmt* pPara = (ParaRstFmt*)pArgs;
1690 
1691         SwTxtFmtColl* pFmt = static_cast<SwTxtFmtColl*>(pPara->pFmtColl);
1692         if ( pPara->bReset )
1693         {
1694 
1695             if( pFmt->GetAttrOutlineLevel() == 0 && pPara )
1696                 pPara->bKeepOutlineLevelAttr = true;
1697 
1698             lcl_RstAttr( pCNd, pPara );
1699 
1700             // --> OD 2007-11-06 #i62675#
1701             // --> OD 2008-04-15 #refactorlists#
1702             // check, if paragraph style has changed
1703             if ( pPara->bResetListAttrs &&
1704                  pFmt != pCNd->GetFmtColl() &&
1705                  pFmt->GetItemState( RES_PARATR_NUMRULE ) == SFX_ITEM_SET )
1706             {
1707                 // --> OD 2009-09-07 #b6876367#
1708                 // Check, if the list style of the paragraph will change.
1709                 bool bChangeOfListStyleAtParagraph( true );
1710                 SwTxtNode* pTNd( dynamic_cast<SwTxtNode*>(pCNd) );
1711                 ASSERT( pTNd,
1712                         "<lcl_SetTxtFmtColl(..)> - text node expected -> crash" );
1713                 {
1714                     SwNumRule* pNumRuleAtParagraph( pTNd->GetNumRule() );
1715                     if ( pNumRuleAtParagraph )
1716                     {
1717                         const SwNumRuleItem& rNumRuleItemAtParagraphStyle =
1718                                                             pFmt->GetNumRule();
1719                         if ( rNumRuleItemAtParagraphStyle.GetValue() ==
1720                                                 pNumRuleAtParagraph->GetName() )
1721                         {
1722                             bChangeOfListStyleAtParagraph = false;
1723                         }
1724                     }
1725                 }
1726 
1727                 if ( bChangeOfListStyleAtParagraph )
1728                 {
1729                     // --> OD 2008-04-08 #refactorlists#
1730                     std::auto_ptr< SwRegHistory > pRegH;
1731                     if ( pPara->pHistory )
1732                     {
1733                         pRegH.reset( new SwRegHistory( pTNd, *pTNd, pPara->pHistory ) );
1734                     }
1735 
1736                     pCNd->ResetAttr( RES_PARATR_NUMRULE );
1737 
1738                     // reset all list attributes
1739                     pCNd->ResetAttr( RES_PARATR_LIST_LEVEL );
1740                     pCNd->ResetAttr( RES_PARATR_LIST_ISRESTART );
1741                     pCNd->ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
1742                     pCNd->ResetAttr( RES_PARATR_LIST_ISCOUNTED );
1743                     pCNd->ResetAttr( RES_PARATR_LIST_ID );
1744                 }
1745                 // <--
1746             }
1747             // <--
1748         }
1749 
1750         // erst in die History aufnehmen, damit ggfs. alte Daten
1751         // gesichert werden koennen
1752         if( pPara->pHistory )
1753             pPara->pHistory->Add( pCNd->GetFmtColl(), pCNd->GetIndex(),
1754                                     ND_TEXTNODE );
1755 
1756         pCNd->ChgFmtColl( pFmt );
1757 
1758         pPara->nWhich++;
1759     }
1760     return sal_True;
1761 }
1762 
1763 sal_Bool SwDoc::SetTxtFmtColl( const SwPaM &rRg,
1764                            SwTxtFmtColl *pFmt,
1765                            bool bReset,
1766                            bool bResetListAttrs )
1767 {
1768     SwDataChanged aTmp( rRg, 0 );
1769     const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End();
1770     SwHistory* pHst = 0;
1771     sal_Bool bRet = sal_True;
1772 
1773     if (GetIDocumentUndoRedo().DoesUndo())
1774     {
1775         // --> OD 2008-04-15 #refactorlists#
1776         SwUndoFmtColl* pUndo = new SwUndoFmtColl( rRg, pFmt,
1777                                                   bReset,
1778                                                   bResetListAttrs );
1779         // <--
1780         pHst = pUndo->GetHistory();
1781         GetIDocumentUndoRedo().AppendUndo(pUndo);
1782     }
1783 
1784     ParaRstFmt aPara( pStt, pEnd, pHst );
1785     aPara.pFmtColl = pFmt;
1786     aPara.bReset = bReset;
1787     // --> OD 2007-11-06 #i62675#
1788     aPara.bResetListAttrs = bResetListAttrs;
1789     // <--
1790 
1791     GetNodes().ForEach( pStt->nNode.GetIndex(), pEnd->nNode.GetIndex()+1,
1792                         lcl_SetTxtFmtColl, &aPara );
1793     if( !aPara.nWhich )
1794         bRet = sal_False;           // keinen gueltigen Node gefunden
1795 
1796     if( bRet )
1797         SetModified();
1798     return bRet;
1799 }
1800 
1801 
1802 // ---- Kopiere die Formate in sich selbst (SwDoc) ----------------------
1803 
1804 SwFmt* SwDoc::CopyFmt( const SwFmt& rFmt,
1805                         const SvPtrarr& rFmtArr,
1806                         FNCopyFmt fnCopyFmt, const SwFmt& rDfltFmt )
1807 {
1808     //  kein-Autoformat || default Format || Collection-Format
1809     // dann suche danach.
1810     if( !rFmt.IsAuto() || !rFmt.GetRegisteredIn() )
1811         for( sal_uInt16 n = 0; n < rFmtArr.Count(); n++ )
1812         {
1813             // ist die Vorlage schon im Doc vorhanden ??
1814             if( ((SwFmt*)rFmtArr[n])->GetName().Equals( rFmt.GetName() ))
1815                 return (SwFmt*)rFmtArr[n];
1816         }
1817 
1818     // suche erstmal nach dem "Parent"
1819     SwFmt* pParent = (SwFmt*)&rDfltFmt;
1820     if( rFmt.DerivedFrom() && pParent != rFmt.DerivedFrom() )
1821         pParent = CopyFmt( *rFmt.DerivedFrom(), rFmtArr,
1822                                 fnCopyFmt, rDfltFmt );
1823 
1824     // erzeuge das Format und kopiere die Attribute
1825     // --> OD 2005-01-13 #i40550#
1826     SwFmt* pNewFmt = (this->*fnCopyFmt)( rFmt.GetName(), pParent, sal_False, sal_True );
1827     // <--
1828     pNewFmt->SetAuto( rFmt.IsAuto() );
1829     pNewFmt->CopyAttrs( rFmt, sal_True );           // kopiere Attribute
1830 
1831     pNewFmt->SetPoolFmtId( rFmt.GetPoolFmtId() );
1832     pNewFmt->SetPoolHelpId( rFmt.GetPoolHelpId() );
1833 
1834     // HelpFile-Id immer auf dflt setzen !!
1835     pNewFmt->SetPoolHlpFileId( UCHAR_MAX );
1836 
1837     return pNewFmt;
1838 }
1839 
1840 
1841 // ---- kopiere das Frame-Format --------
1842 SwFrmFmt* SwDoc::CopyFrmFmt( const SwFrmFmt& rFmt )
1843 {
1844 
1845     return (SwFrmFmt*)CopyFmt( rFmt, *GetFrmFmts(), &SwDoc::_MakeFrmFmt,
1846                                 *GetDfltFrmFmt() );
1847 }
1848 
1849 // ---- kopiere das Char-Format --------
1850 SwCharFmt* SwDoc::CopyCharFmt( const SwCharFmt& rFmt )
1851 {
1852     return (SwCharFmt*)CopyFmt( rFmt, *GetCharFmts(),
1853                                 &SwDoc::_MakeCharFmt,
1854                                 *GetDfltCharFmt() );
1855 }
1856 
1857 
1858 // --- Kopiere TextNodes ----
1859 
1860 SwTxtFmtColl* SwDoc::CopyTxtColl( const SwTxtFmtColl& rColl )
1861 {
1862     SwTxtFmtColl* pNewColl = FindTxtFmtCollByName( rColl.GetName() );
1863     if( pNewColl )
1864         return pNewColl;
1865 
1866     // suche erstmal nach dem "Parent"
1867     SwTxtFmtColl* pParent = pDfltTxtFmtColl;
1868     if( pParent != rColl.DerivedFrom() )
1869         pParent = CopyTxtColl( *(SwTxtFmtColl*)rColl.DerivedFrom() );
1870 
1871 
1872 //FEATURE::CONDCOLL
1873     if( RES_CONDTXTFMTCOLL == rColl.Which() )
1874     {
1875         pNewColl = new SwConditionTxtFmtColl( GetAttrPool(), rColl.GetName(),
1876                                                 pParent);
1877         pTxtFmtCollTbl->Insert( pNewColl, pTxtFmtCollTbl->Count() );
1878         pNewColl->SetAuto( sal_False );
1879         SetModified();
1880 
1881         // Kopiere noch die Bedingungen
1882         ((SwConditionTxtFmtColl*)pNewColl)->SetConditions(
1883                             ((SwConditionTxtFmtColl&)rColl).GetCondColls() );
1884     }
1885     else
1886 //FEATURE::CONDCOLL
1887         pNewColl = MakeTxtFmtColl( rColl.GetName(), pParent );
1888 
1889     // kopiere jetzt noch die Auto-Formate oder kopiere die Attribute
1890     pNewColl->CopyAttrs( rColl, sal_True );
1891 
1892     // setze noch den Outline-Level
1893     //if( NO_NUMBERING != rColl.GetOutlineLevel() ) //#outline level,zhaojianwei
1894     //  pNewColl->SetOutlineLevel( rColl.GetOutlineLevel() );
1895     if(rColl.IsAssignedToListLevelOfOutlineStyle())
1896         pNewColl->AssignToListLevelOfOutlineStyle(rColl.GetAssignedOutlineStyleLevel());//<-end,zhaojianwei
1897     //<-end
1898     pNewColl->SetPoolFmtId( rColl.GetPoolFmtId() );
1899     pNewColl->SetPoolHelpId( rColl.GetPoolHelpId() );
1900 
1901     // HelpFile-Id immer auf dflt setzen !!
1902     pNewColl->SetPoolHlpFileId( UCHAR_MAX );
1903 
1904     if( &rColl.GetNextTxtFmtColl() != &rColl )
1905         pNewColl->SetNextTxtFmtColl( *CopyTxtColl( rColl.GetNextTxtFmtColl() ));
1906 
1907     // ggfs. die NumRule erzeugen
1908     if( this != rColl.GetDoc() )
1909     {
1910         const SfxPoolItem* pItem;
1911         if( SFX_ITEM_SET == pNewColl->GetItemState( RES_PARATR_NUMRULE,
1912             sal_False, &pItem ))
1913         {
1914             const SwNumRule* pRule;
1915             const String& rName = ((SwNumRuleItem*)pItem)->GetValue();
1916             if( rName.Len() &&
1917                 0 != ( pRule = rColl.GetDoc()->FindNumRulePtr( rName )) &&
1918                 !pRule->IsAutoRule() )
1919             {
1920                 SwNumRule* pDestRule = FindNumRulePtr( rName );
1921                 if( pDestRule )
1922                     pDestRule->SetInvalidRule( sal_True );
1923                 else
1924                     MakeNumRule( rName, pRule );
1925             }
1926         }
1927     }
1928     return pNewColl;
1929 }
1930 
1931 // --- Kopiere GrafikNodes ----
1932 
1933 SwGrfFmtColl* SwDoc::CopyGrfColl( const SwGrfFmtColl& rColl )
1934 {
1935     SwGrfFmtColl* pNewColl = FindGrfFmtCollByName( rColl.GetName() );
1936     if( pNewColl )
1937         return pNewColl;
1938 
1939     // suche erstmal nach dem "Parent"
1940     SwGrfFmtColl* pParent = pDfltGrfFmtColl;
1941     if( pParent != rColl.DerivedFrom() )
1942         pParent = CopyGrfColl( *(SwGrfFmtColl*)rColl.DerivedFrom() );
1943 
1944     // falls nicht, so kopiere sie
1945     pNewColl = MakeGrfFmtColl( rColl.GetName(), pParent );
1946 
1947     // noch die Attribute kopieren
1948     pNewColl->CopyAttrs( rColl );
1949 
1950     pNewColl->SetPoolFmtId( rColl.GetPoolFmtId() );
1951     pNewColl->SetPoolHelpId( rColl.GetPoolHelpId() );
1952 
1953     // HelpFile-Id immer auf dflt setzen !!
1954     pNewColl->SetPoolHlpFileId( UCHAR_MAX );
1955 
1956     return pNewColl;
1957 }
1958 
1959 SwPageDesc* lcl_FindPageDesc( const SwPageDescs& rArr, const String& rName )
1960 {
1961     for( sal_uInt16 n = rArr.Count(); n; )
1962     {
1963         SwPageDesc* pDesc = rArr[ --n ];
1964         if( pDesc->GetName() == rName )
1965             return pDesc;
1966     }
1967     return 0;
1968 }
1969 
1970 void SwDoc::CopyFmtArr( const SvPtrarr& rSourceArr,
1971                         SvPtrarr& rDestArr,
1972                         FNCopyFmt fnCopyFmt,
1973                         SwFmt& rDfltFmt )
1974 {
1975     sal_uInt16 nSrc;
1976     SwFmt* pSrc, *pDest;
1977 
1978     // 1. Schritt alle Formate anlegen (das 0. ueberspringen - Default!)
1979     for( nSrc = rSourceArr.Count(); nSrc > 1; )
1980     {
1981         pSrc = (SwFmt*)rSourceArr[ --nSrc ];
1982         if( pSrc->IsDefault() || pSrc->IsAuto() )
1983             continue;
1984 
1985         if( 0 == FindFmtByName( rDestArr, pSrc->GetName() ) )
1986         {
1987             if( RES_CONDTXTFMTCOLL == pSrc->Which() )
1988                 MakeCondTxtFmtColl( pSrc->GetName(), (SwTxtFmtColl*)&rDfltFmt );
1989             else
1990                 // --> OD 2005-01-13 #i40550#
1991                 (this->*fnCopyFmt)( pSrc->GetName(), &rDfltFmt, sal_False, sal_True );
1992                 // <--
1993         }
1994     }
1995 
1996     // 2. Schritt alle Attribute kopieren, richtige Parents setzen
1997     for( nSrc = rSourceArr.Count(); nSrc > 1; )
1998     {
1999         pSrc = (SwFmt*)rSourceArr[ --nSrc ];
2000         if( pSrc->IsDefault() || pSrc->IsAuto() )
2001             continue;
2002 
2003         pDest = FindFmtByName( rDestArr, pSrc->GetName() );
2004         pDest->SetAuto( sal_False );
2005         pDest->DelDiffs( *pSrc );
2006 
2007         // #i94285#: existing <SwFmtPageDesc> instance, before copying attributes
2008         const SfxPoolItem* pItem;
2009         if( &GetAttrPool() != pSrc->GetAttrSet().GetPool() &&
2010             SFX_ITEM_SET == pSrc->GetAttrSet().GetItemState(
2011             RES_PAGEDESC, sal_False, &pItem ) &&
2012             ((SwFmtPageDesc*)pItem)->GetPageDesc() )
2013         {
2014             SwFmtPageDesc aPageDesc( *(SwFmtPageDesc*)pItem );
2015             const String& rNm = aPageDesc.GetPageDesc()->GetName();
2016             SwPageDesc* pPageDesc = ::lcl_FindPageDesc( aPageDescs, rNm );
2017             if( !pPageDesc )
2018             {
2019                 pPageDesc = aPageDescs[ MakePageDesc( rNm ) ];
2020             }
2021             aPageDesc.RegisterToPageDesc( *pPageDesc );
2022             SwAttrSet aTmpAttrSet( pSrc->GetAttrSet() );
2023             aTmpAttrSet.Put( aPageDesc );
2024             pDest->SetFmtAttr( aTmpAttrSet );
2025         }
2026         else
2027         {
2028             pDest->SetFmtAttr( pSrc->GetAttrSet() );
2029         }
2030 
2031         pDest->SetPoolFmtId( pSrc->GetPoolFmtId() );
2032         pDest->SetPoolHelpId( pSrc->GetPoolHelpId() );
2033 
2034         // HelpFile-Id immer auf dflt setzen !!
2035         pDest->SetPoolHlpFileId( UCHAR_MAX );
2036 
2037         if( pSrc->DerivedFrom() )
2038             pDest->SetDerivedFrom( FindFmtByName( rDestArr,
2039                                         pSrc->DerivedFrom()->GetName() ) );
2040         if( RES_TXTFMTCOLL == pSrc->Which() ||
2041             RES_CONDTXTFMTCOLL == pSrc->Which() )
2042         {
2043             SwTxtFmtColl* pSrcColl = (SwTxtFmtColl*)pSrc,
2044                         * pDstColl = (SwTxtFmtColl*)pDest;
2045             if( &pSrcColl->GetNextTxtFmtColl() != pSrcColl )
2046                 pDstColl->SetNextTxtFmtColl( *(SwTxtFmtColl*)FindFmtByName(
2047                     rDestArr, pSrcColl->GetNextTxtFmtColl().GetName() ) );
2048 
2049             // setze noch den Outline-Level
2050             //if( NO_NUMBERING != pSrcColl->GetOutlineLevel() ) //#outline level,zhaojianwei
2051             //  pDstColl->SetOutlineLevel( pSrcColl->GetOutlineLevel() );
2052             if(pSrcColl->IsAssignedToListLevelOfOutlineStyle())
2053                 pDstColl->AssignToListLevelOfOutlineStyle(pSrcColl->GetAssignedOutlineStyleLevel());//<-end,zhaojianwei
2054             //<-end
2055 
2056 //FEATURE::CONDCOLL
2057             if( RES_CONDTXTFMTCOLL == pSrc->Which() )
2058                 // Kopiere noch die Bedingungen
2059                 // aber erst die alten loeschen!
2060                 ((SwConditionTxtFmtColl*)pDstColl)->SetConditions(
2061                             ((SwConditionTxtFmtColl*)pSrc)->GetCondColls() );
2062 //FEATURE::CONDCOLL
2063         }
2064     }
2065 }
2066 
2067 void SwDoc::CopyPageDescHeaderFooterImpl( bool bCpyHeader,
2068                                 const SwFrmFmt& rSrcFmt, SwFrmFmt& rDestFmt )
2069 {
2070     // jetzt noch Header-/Footer-Attribute richtig behandeln
2071     // Contenten Nodes Dokumentuebergreifend kopieren!
2072     sal_uInt16 nAttr = static_cast<sal_uInt16>( bCpyHeader ? RES_HEADER : RES_FOOTER );
2073     const SfxPoolItem* pItem;
2074     if( SFX_ITEM_SET != rSrcFmt.GetAttrSet().GetItemState( nAttr, sal_False, &pItem ))
2075         return ;
2076 
2077     // Im Header steht noch der Verweis auf das Format aus dem
2078     // anderen Document!!
2079     SfxPoolItem* pNewItem = pItem->Clone();
2080 
2081     SwFrmFmt* pOldFmt;
2082     if( bCpyHeader )
2083          pOldFmt = ((SwFmtHeader*)pNewItem)->GetHeaderFmt();
2084     else
2085          pOldFmt = ((SwFmtFooter*)pNewItem)->GetFooterFmt();
2086 
2087     if( pOldFmt )
2088     {
2089         SwFrmFmt* pNewFmt = new SwFrmFmt( GetAttrPool(), "CpyDesc",
2090                                             GetDfltFrmFmt() );
2091         pNewFmt->CopyAttrs( *pOldFmt, sal_True );
2092 
2093         if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState(
2094             RES_CNTNT, sal_False, &pItem ))
2095         {
2096             SwFmtCntnt* pCntnt = (SwFmtCntnt*)pItem;
2097             if( pCntnt->GetCntntIdx() )
2098             {
2099                 SwNodeIndex aTmpIdx( GetNodes().GetEndOfAutotext() );
2100                 const SwNodes& rSrcNds = rSrcFmt.GetDoc()->GetNodes();
2101                 SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmpIdx,
2102                                                 bCpyHeader
2103                                                     ? SwHeaderStartNode
2104                                                     : SwFooterStartNode );
2105                 const SwNode& rCSttNd = pCntnt->GetCntntIdx()->GetNode();
2106                 SwNodeRange aRg( rCSttNd, 0, *rCSttNd.EndOfSectionNode() );
2107                 aTmpIdx = *pSttNd->EndOfSectionNode();
2108                 rSrcNds._Copy( aRg, aTmpIdx );
2109                 aTmpIdx = *pSttNd;
2110                 rSrcFmt.GetDoc()->CopyFlyInFlyImpl( aRg, 0, aTmpIdx );
2111                 pNewFmt->SetFmtAttr( SwFmtCntnt( pSttNd ));
2112             }
2113             else
2114                 pNewFmt->ResetFmtAttr( RES_CNTNT );
2115         }
2116         if( bCpyHeader )
2117             ((SwFmtHeader*)pNewItem)->RegisterToFormat(*pNewFmt);
2118         else
2119             ((SwFmtFooter*)pNewItem)->RegisterToFormat(*pNewFmt);
2120         rDestFmt.SetFmtAttr( *pNewItem );
2121     }
2122     delete pNewItem;
2123 }
2124 
2125 void SwDoc::CopyPageDesc( const SwPageDesc& rSrcDesc, SwPageDesc& rDstDesc,
2126                             sal_Bool bCopyPoolIds )
2127 {
2128     sal_Bool bNotifyLayout = sal_False;
2129     SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219
2130 
2131     rDstDesc.SetLandscape( rSrcDesc.GetLandscape() );
2132     rDstDesc.SetNumType( rSrcDesc.GetNumType() );
2133     if( rDstDesc.ReadUseOn() != rSrcDesc.ReadUseOn() )
2134     {
2135         rDstDesc.WriteUseOn( rSrcDesc.ReadUseOn() );
2136         bNotifyLayout = sal_True;
2137     }
2138 
2139     if( bCopyPoolIds )
2140     {
2141         rDstDesc.SetPoolFmtId( rSrcDesc.GetPoolFmtId() );
2142         rDstDesc.SetPoolHelpId( rSrcDesc.GetPoolHelpId() );
2143         // HelpFile-Id immer auf dflt setzen !!
2144         rDstDesc.SetPoolHlpFileId( UCHAR_MAX );
2145     }
2146 
2147     if( rSrcDesc.GetFollow() != &rSrcDesc )
2148     {
2149         SwPageDesc* pFollow = ::lcl_FindPageDesc( aPageDescs,
2150                                     rSrcDesc.GetFollow()->GetName() );
2151         if( !pFollow )
2152         {
2153             // dann mal kopieren
2154             sal_uInt16 nPos = MakePageDesc( rSrcDesc.GetFollow()->GetName() );
2155             pFollow = aPageDescs[ nPos ];
2156             CopyPageDesc( *rSrcDesc.GetFollow(), *pFollow );
2157         }
2158         rDstDesc.SetFollow( pFollow );
2159         bNotifyLayout = sal_True;
2160     }
2161 
2162     // die Header/Footer-Attribute werden gesondert kopiert, die Content-
2163     // Sections muessen vollstaendig mitgenommen werden!
2164     {
2165         SfxItemSet aAttrSet( rSrcDesc.GetMaster().GetAttrSet() );
2166         aAttrSet.ClearItem( RES_HEADER );
2167         aAttrSet.ClearItem( RES_FOOTER );
2168 
2169         rDstDesc.GetMaster().DelDiffs( aAttrSet );
2170         rDstDesc.GetMaster().SetFmtAttr( aAttrSet );
2171 
2172         aAttrSet.ClearItem();
2173         aAttrSet.Put( rSrcDesc.GetLeft().GetAttrSet() );
2174         aAttrSet.ClearItem( RES_HEADER );
2175         aAttrSet.ClearItem( RES_FOOTER );
2176 
2177         rDstDesc.GetLeft().DelDiffs( aAttrSet );
2178         rDstDesc.GetLeft().SetFmtAttr( aAttrSet );
2179     }
2180 
2181     CopyHeader( rSrcDesc.GetMaster(), rDstDesc.GetMaster() );
2182     CopyFooter( rSrcDesc.GetMaster(), rDstDesc.GetMaster() );
2183     if( !rDstDesc.IsHeaderShared() )
2184         CopyHeader( rSrcDesc.GetLeft(), rDstDesc.GetLeft() );
2185     else
2186         rDstDesc.GetLeft().SetFmtAttr( rDstDesc.GetMaster().GetHeader() );
2187 
2188     if( !rDstDesc.IsFooterShared() )
2189         CopyFooter( rSrcDesc.GetLeft(), rDstDesc.GetLeft() );
2190     else
2191         rDstDesc.GetLeft().SetFmtAttr( rDstDesc.GetMaster().GetFooter() );
2192 
2193     if( bNotifyLayout && pTmpRoot )
2194     {
2195         std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080225
2196         std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs));//swmod 080226
2197     }
2198 
2199     //Wenn sich FussnotenInfo veraendert, so werden die Seiten
2200     //angetriggert.
2201     if( !(rDstDesc.GetFtnInfo() == rSrcDesc.GetFtnInfo()) )
2202     {
2203         rDstDesc.SetFtnInfo( rSrcDesc.GetFtnInfo() );
2204         SwMsgPoolItem  aInfo( RES_PAGEDESC_FTNINFO );
2205         {
2206             rDstDesc.GetMaster().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) );
2207         }
2208         {
2209             rDstDesc.GetLeft().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) );
2210         }
2211     }
2212 }
2213 
2214 void SwDoc::ReplaceStyles( SwDoc& rSource )
2215 {
2216     ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
2217 
2218     CopyFmtArr( *rSource.pCharFmtTbl, *pCharFmtTbl,
2219                 &SwDoc::_MakeCharFmt, *pDfltCharFmt );
2220     CopyFmtArr( *rSource.pFrmFmtTbl, *pFrmFmtTbl,
2221                 &SwDoc::_MakeFrmFmt, *pDfltFrmFmt );
2222     CopyFmtArr( *rSource.pTxtFmtCollTbl, *pTxtFmtCollTbl,
2223                 &SwDoc::_MakeTxtFmtColl, *pDfltTxtFmtColl );
2224 
2225     // und jetzt noch die Seiten-Vorlagen
2226     sal_uInt16 nCnt = rSource.aPageDescs.Count();
2227     if( nCnt )
2228     {
2229         // ein anderes Doc -> Numberformatter muessen gemergt werden
2230         SwTblNumFmtMerge aTNFM( rSource, *this );
2231 
2232         // 1. Schritt alle Formate anlegen (das 0. ueberspringen - Default!)
2233         while( nCnt )
2234         {
2235             SwPageDesc *pSrc = rSource.aPageDescs[ --nCnt ];
2236             if( 0 == ::lcl_FindPageDesc( aPageDescs, pSrc->GetName() ) )
2237                 MakePageDesc( pSrc->GetName() );
2238         }
2239 
2240         // 2. Schritt alle Attribute kopieren, richtige Parents setzen
2241         for( nCnt = rSource.aPageDescs.Count(); nCnt; )
2242         {
2243             SwPageDesc *pSrc = rSource.aPageDescs[ --nCnt ];
2244             CopyPageDesc( *pSrc, *::lcl_FindPageDesc( aPageDescs, pSrc->GetName() ));
2245         }
2246     }
2247 
2248     //JP 08.04.99: und dann sind da noch die Numerierungs-Vorlagen
2249     nCnt = rSource.GetNumRuleTbl().Count();
2250     if( nCnt )
2251     {
2252         const SwNumRuleTbl& rArr = rSource.GetNumRuleTbl();
2253         for( sal_uInt16 n = 0; n < nCnt; ++n )
2254         {
2255             const SwNumRule& rR = *rArr[ n ];
2256             if( !rR.IsAutoRule() )
2257             {
2258                 SwNumRule* pNew = FindNumRulePtr( rR.GetName());
2259                 if( pNew )
2260                     pNew->CopyNumRule( this, rR );
2261                 else
2262                     MakeNumRule( rR.GetName(), &rR );
2263             }
2264         }
2265     }
2266 
2267     if (undoGuard.UndoWasEnabled())
2268     {
2269         // nodes array was modified!
2270         GetIDocumentUndoRedo().DelAllUndoObj();
2271     }
2272 
2273     SetModified();
2274 }
2275 
2276 SwFmt* SwDoc::FindFmtByName( const SvPtrarr& rFmtArr,
2277                                     const String& rName ) const
2278 {
2279     SwFmt* pFnd = 0;
2280     for( sal_uInt16 n = 0; n < rFmtArr.Count(); n++ )
2281     {
2282         // ist die Vorlage schon im Doc vorhanden ??
2283         if( ((SwFmt*)rFmtArr[n])->GetName() == rName )
2284         {
2285             pFnd = (SwFmt*)rFmtArr[n];
2286             break;
2287         }
2288     }
2289     return pFnd;
2290 }
2291 
2292 void SwDoc::MoveLeftMargin( const SwPaM& rPam, sal_Bool bRight, sal_Bool bModulus )
2293 {
2294     SwHistory* pHistory = 0;
2295     if (GetIDocumentUndoRedo().DoesUndo())
2296     {
2297         SwUndoMoveLeftMargin* pUndo = new SwUndoMoveLeftMargin( rPam, bRight,
2298                                                                 bModulus );
2299         pHistory = &pUndo->GetHistory();
2300         GetIDocumentUndoRedo().AppendUndo( pUndo );
2301     }
2302 
2303     const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDefault( RES_PARATR_TABSTOP );
2304     sal_uInt16 nDefDist = rTabItem.Count() ?
2305         static_cast<sal_uInt16>(rTabItem[0].GetTabPos()) : 1134;
2306     const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End();
2307     SwNodeIndex aIdx( rStt.nNode );
2308     while( aIdx <= rEnd.nNode )
2309     {
2310         SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode();
2311         if( pTNd )
2312         {
2313             SvxLRSpaceItem aLS( (SvxLRSpaceItem&)pTNd->SwCntntNode::GetAttr( RES_LR_SPACE ) );
2314 
2315             // --> FME 2008-09-16 #i93873# See also lcl_MergeListLevelIndentAsLRSpaceItem in thints.cxx
2316             if ( pTNd->AreListLevelIndentsApplicable() )
2317             {
2318                 const SwNumRule* pRule = pTNd->GetNumRule();
2319                 if ( pRule )
2320                 {
2321                     const int nListLevel = pTNd->GetActualListLevel();
2322                     if ( nListLevel >= 0 )
2323                     {
2324                         const SwNumFmt& rFmt = pRule->Get(static_cast<sal_uInt16>(nListLevel));
2325                         if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
2326                         {
2327                             aLS.SetTxtLeft( rFmt.GetIndentAt() );
2328                             aLS.SetTxtFirstLineOfst( static_cast<short>(rFmt.GetFirstLineIndent()) );
2329                         }
2330                     }
2331                 }
2332             }
2333 
2334             long nNext = aLS.GetTxtLeft();
2335             if( bModulus )
2336                 nNext = ( nNext / nDefDist ) * nDefDist;
2337 
2338             if( bRight )
2339                 nNext += nDefDist;
2340             else
2341                 nNext -= nDefDist;
2342 
2343             aLS.SetTxtLeft( nNext );
2344 
2345             SwRegHistory aRegH( pTNd, *pTNd, pHistory );
2346             pTNd->SetAttr( aLS );
2347         }
2348         aIdx++;
2349     }
2350     SetModified();
2351 }
2352 
2353 sal_Bool SwDoc::DontExpandFmt( const SwPosition& rPos, sal_Bool bFlag )
2354 {
2355     sal_Bool bRet = sal_False;
2356     SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
2357     if( pTxtNd )
2358     {
2359         bRet = pTxtNd->DontExpandFmt( rPos.nContent, bFlag );
2360         if( bRet && GetIDocumentUndoRedo().DoesUndo() )
2361         {
2362             GetIDocumentUndoRedo().AppendUndo( new SwUndoDontExpandFmt(rPos) );
2363         }
2364     }
2365     return bRet;
2366 }
2367 
2368 SwTableBoxFmt* SwDoc::MakeTableBoxFmt()
2369 {
2370     SwTableBoxFmt* pFmt = new SwTableBoxFmt( GetAttrPool(), aEmptyStr,
2371                                                 pDfltFrmFmt );
2372     SetModified();
2373     return pFmt;
2374 }
2375 
2376 SwTableLineFmt* SwDoc::MakeTableLineFmt()
2377 {
2378     SwTableLineFmt* pFmt = new SwTableLineFmt( GetAttrPool(), aEmptyStr,
2379                                                 pDfltFrmFmt );
2380     SetModified();
2381     return pFmt;
2382 }
2383 
2384 void SwDoc::_CreateNumberFormatter()
2385 {
2386     RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722",  "SwDoc::_CreateNumberFormatter" );
2387 
2388     ASSERT( !pNumberFormatter, "ist doch schon vorhanden" );
2389 
2390 
2391     LanguageType eLang = LANGUAGE_SYSTEM; //System::GetLanguage();
2392 /*              ((const SvxLanguageItem&)GetAttrPool().
2393                     GetDefaultItem( RES_CHRATR_LANGUAGE )).GetLanguage();
2394 */
2395     Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
2396     pNumberFormatter = new SvNumberFormatter( xMSF, eLang );
2397     pNumberFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_FORMAT_INTL );
2398     pNumberFormatter->SetYear2000(static_cast<sal_uInt16>(::utl::MiscCfg().GetYear2000()));
2399 
2400 }
2401 
2402 SwTblNumFmtMerge::SwTblNumFmtMerge( const SwDoc& rSrc, SwDoc& rDest )
2403     : pNFmt( 0 )
2404 {
2405     // ein anderes Doc -> Numberformatter muessen gemergt werden
2406     SvNumberFormatter* pN;
2407     if( &rSrc != &rDest && 0 != ( pN = ((SwDoc&)rSrc).GetNumberFormatter( sal_False ) ))
2408         ( pNFmt = rDest.GetNumberFormatter( sal_True ))->MergeFormatter( *pN );
2409 
2410     if( &rSrc != &rDest )
2411         ((SwGetRefFieldType*)rSrc.GetSysFldType( RES_GETREFFLD ))->
2412             MergeWithOtherDoc( rDest );
2413 }
2414 
2415 SwTblNumFmtMerge::~SwTblNumFmtMerge()
2416 {
2417     if( pNFmt )
2418         pNFmt->ClearMergeTable();
2419 }
2420 
2421 
2422 void SwDoc::SetTxtFmtCollByAutoFmt( const SwPosition& rPos, sal_uInt16 nPoolId,
2423                                     const SfxItemSet* pSet )
2424 {
2425     SwPaM aPam( rPos );
2426     SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode();
2427 
2428     if( mbIsAutoFmtRedline && pTNd )
2429     {
2430         // dann das Redline Object anlegen
2431         const SwTxtFmtColl& rColl = *pTNd->GetTxtColl();
2432         SwRedline* pRedl = new SwRedline( nsRedlineType_t::REDLINE_FMTCOLL, aPam );
2433         pRedl->SetMark();
2434 
2435         // interressant sind nur die Items, die vom Set NICHT wieder
2436         // in den Node gesetzt werden. Also muss man die Differenz nehmen
2437         SwRedlineExtraData_FmtColl aExtraData( rColl.GetName(),
2438                                                 rColl.GetPoolFmtId() );
2439         if( pSet && pTNd->HasSwAttrSet() )
2440         {
2441             SfxItemSet aTmp( *pTNd->GetpSwAttrSet() );
2442             aTmp.Differentiate( *pSet );
2443             // das Adjust Item behalten wir extra
2444             const SfxPoolItem* pItem;
2445             if( SFX_ITEM_SET == pTNd->GetpSwAttrSet()->GetItemState(
2446                     RES_PARATR_ADJUST, sal_False, &pItem ))
2447                 aTmp.Put( *pItem );
2448             aExtraData.SetItemSet( aTmp );
2449         }
2450         pRedl->SetExtraData( &aExtraData );
2451 
2452 // !!!!!!!!! Undo fehlt noch !!!!!!!!!!!!!!!!!!
2453         AppendRedline( pRedl, true );
2454     }
2455 
2456     SetTxtFmtColl( aPam, GetTxtCollFromPool( nPoolId ) );
2457 
2458     if( pSet && pTNd && pSet->Count() )
2459     {
2460         aPam.SetMark();
2461         aPam.GetMark()->nContent.Assign( pTNd, pTNd->GetTxt().Len() );
2462         InsertItemSet( aPam, *pSet, 0 );
2463     }
2464 }
2465 
2466 void SwDoc::SetFmtItemByAutoFmt( const SwPaM& rPam, const SfxItemSet& rSet )
2467 {
2468     SwTxtNode* pTNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode();
2469 
2470     RedlineMode_t eOld = GetRedlineMode();
2471 
2472     if( mbIsAutoFmtRedline && pTNd )
2473     {
2474         // dann das Redline Object anlegen
2475         SwRedline* pRedl = new SwRedline( nsRedlineType_t::REDLINE_FORMAT, rPam );
2476         if( !pRedl->HasMark() )
2477             pRedl->SetMark();
2478 
2479         // interressant sind nur die Items, die vom Set NICHT wieder
2480         // in den Node gesetzt werden. Also muss man die Differenz nehmen
2481         SwRedlineExtraData_Format aExtraData( rSet );
2482 
2483 /*
2484         if( pSet && pTNd->HasSwAttrSet() )
2485         {
2486             SfxItemSet aTmp( *pTNd->GetpSwAttrSet() );
2487             aTmp.Differentiate( *pSet );
2488             // das Adjust Item behalten wir extra
2489             const SfxPoolItem* pItem;
2490             if( SFX_ITEM_SET == pTNd->GetpSwAttrSet()->GetItemState(
2491                     RES_PARATR_ADJUST, sal_False, &pItem ))
2492                 aTmp.Put( *pItem );
2493             aExtraData.SetItemSet( aTmp );
2494         }
2495 */
2496         pRedl->SetExtraData( &aExtraData );
2497 
2498 // !!!!!!!!! Undo fehlt noch !!!!!!!!!!!!!!!!!!
2499         AppendRedline( pRedl, true );
2500 
2501         SetRedlineMode_intern( (RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
2502     }
2503 
2504     InsertItemSet( rPam, rSet, nsSetAttrMode::SETATTR_DONTEXPAND );
2505     SetRedlineMode_intern( eOld );
2506 }
2507 
2508 void SwDoc::ChgFmt(SwFmt & rFmt, const SfxItemSet & rSet)
2509 {
2510     if (GetIDocumentUndoRedo().DoesUndo())
2511     {
2512         // copying <rSet> to <aSet>
2513         SfxItemSet aSet(rSet);
2514         // remove from <aSet> all items, which are already set at the format
2515         aSet.Differentiate(rFmt.GetAttrSet());
2516         // <aSet> contains now all *new* items for the format
2517 
2518         // copying current format item set to <aOldSet>
2519         SfxItemSet aOldSet(rFmt.GetAttrSet());
2520         // insert new items into <aOldSet>
2521         aOldSet.Put(aSet);
2522         // invalidate all new items in <aOldSet> in order to clear these items,
2523         // if the undo action is triggered.
2524         {
2525             SfxItemIter aIter(aSet);
2526 
2527             const SfxPoolItem * pItem = aIter.FirstItem();
2528             while (pItem != NULL)
2529             {
2530                 aOldSet.InvalidateItem(pItem->Which());
2531 
2532                 pItem = aIter.NextItem();
2533             }
2534         }
2535 
2536         SwUndo * pUndo = new SwUndoFmtAttr(aOldSet, rFmt);
2537 
2538         GetIDocumentUndoRedo().AppendUndo(pUndo);
2539     }
2540 
2541     rFmt.SetFmtAttr(rSet);
2542 }
2543 
2544 void SwDoc::RenameFmt(SwFmt & rFmt, const String & sNewName,
2545                       sal_Bool bBroadcast)
2546 {
2547     SfxStyleFamily eFamily = SFX_STYLE_FAMILY_ALL;
2548 
2549     if (GetIDocumentUndoRedo().DoesUndo())
2550     {
2551         SwUndo * pUndo = NULL;
2552 
2553         switch (rFmt.Which())
2554         {
2555         case RES_CHRFMT:
2556             pUndo = new SwUndoRenameCharFmt(rFmt.GetName(), sNewName, this);
2557             eFamily = SFX_STYLE_FAMILY_PARA;
2558             break;
2559         case RES_TXTFMTCOLL:
2560             pUndo = new SwUndoRenameFmtColl(rFmt.GetName(), sNewName, this);
2561             eFamily = SFX_STYLE_FAMILY_CHAR;
2562             break;
2563         case RES_FRMFMT:
2564             pUndo = new SwUndoRenameFrmFmt(rFmt.GetName(), sNewName, this);
2565             eFamily = SFX_STYLE_FAMILY_FRAME;
2566             break;
2567 
2568         default:
2569             break;
2570         }
2571 
2572         if (pUndo)
2573         {
2574             GetIDocumentUndoRedo().AppendUndo(pUndo);
2575         }
2576     }
2577 
2578     rFmt.SetName(sNewName);
2579 
2580     if (bBroadcast)
2581         BroadcastStyleOperation(sNewName, eFamily, SFX_STYLESHEET_MODIFIED);
2582 }
2583 
2584 // --> OD 2006-09-27 #i69627#
2585 namespace docfunc
2586 {
2587     bool HasOutlineStyleToBeWrittenAsNormalListStyle( SwDoc& rDoc )
2588     {
2589         // If a parent paragraph style of one of the parargraph styles, which
2590         // are assigned to the list levels of the outline style, has a list style
2591         // set or inherits a list style from its parent style, the outline style
2592         // has to be written as a normal list style to the OpenDocument file
2593         // format or the OpenOffice.org file format.
2594         bool bRet( false );
2595 
2596         const SwTxtFmtColls* pTxtFmtColls( rDoc.GetTxtFmtColls() );
2597         if ( pTxtFmtColls )
2598         {
2599             const sal_uInt16 nCount = pTxtFmtColls->Count();
2600             for ( sal_uInt16 i = 0; i < nCount; ++i )
2601             {
2602                 SwTxtFmtColl* pTxtFmtColl = (*pTxtFmtColls)[i];
2603 
2604                 if ( pTxtFmtColl->IsDefault() ||
2605                    //  pTxtFmtColl->GetOutlineLevel() == NO_NUMBERING ) //#outline level,zhaojianwei
2606                     ! pTxtFmtColl->IsAssignedToListLevelOfOutlineStyle() )  //<-end,zhaojianwei
2607                 {
2608                     continue;
2609                 }
2610 
2611                 const SwTxtFmtColl* pParentTxtFmtColl =
2612                    dynamic_cast<const SwTxtFmtColl*>( pTxtFmtColl->DerivedFrom());
2613                 if ( !pParentTxtFmtColl )
2614                     continue;
2615 
2616                 if ( SFX_ITEM_SET == pParentTxtFmtColl->GetItemState( RES_PARATR_NUMRULE ) )
2617                 {
2618                     // --> OD 2009-11-12 #i106218#
2619                     // consider that the outline style is set
2620                     const SwNumRuleItem& rDirectItem = pParentTxtFmtColl->GetNumRule();
2621                     if ( rDirectItem.GetValue() != rDoc.GetOutlineNumRule()->GetName() )
2622                     {
2623                         bRet = true;
2624                         break;
2625                     }
2626                     // <--
2627                 }
2628             }
2629 
2630         }
2631         return bRet;
2632     }
2633 }
2634 // <--
2635