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