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