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