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 #include <rolbck.hxx>
28
29 #include <tools/resid.hxx>
30
31 #include <svl/itemiter.hxx>
32
33 #include <editeng/brkitem.hxx>
34
35 #include <hints.hxx>
36 #include <hintids.hxx>
37 #include <fmtftn.hxx>
38 #include <fchrfmt.hxx>
39 #include <fmtflcnt.hxx>
40 #include <fmtrfmrk.hxx>
41 #include <fmtfld.hxx>
42 #include <fmtpdsc.hxx>
43 #include <txtfld.hxx>
44 #include <txtrfmrk.hxx>
45 #include <txttxmrk.hxx>
46 #include <txtftn.hxx>
47 #include <txtflcnt.hxx>
48 #include <fmtanchr.hxx>
49 #include <fmtcnct.hxx>
50 #include <frmfmt.hxx>
51 #include <ftnidx.hxx>
52 #include <doc.hxx> // SwDoc.GetNodes()
53 #include <IDocumentUndoRedo.hxx>
54 #include <docary.hxx>
55 #include <ndtxt.hxx> // SwTxtNode
56 #include <paratr.hxx> //
57 #include <cellatr.hxx> //
58 #include <fldbas.hxx> // fuer Felder
59 #include <pam.hxx> // fuer SwPaM
60 #include <swtable.hxx>
61 #include <ndgrf.hxx> // SwGrfNode
62 #include <UndoCore.hxx>
63 #include <IMark.hxx> // fuer SwBookmark
64 #include <charfmt.hxx> // #i27615#
65 #include <comcore.hrc>
66 #include <undo.hrc>
67 #include <bookmrk.hxx>
68
SV_IMPL_PTRARR(SwpHstry,SwHistoryHintPtr)69 SV_IMPL_PTRARR( SwpHstry, SwHistoryHintPtr)
70
71 String SwHistoryHint::GetDescription() const
72 {
73 return String();
74 }
75
76
SwHistorySetFmt(const SfxPoolItem * pFmtHt,sal_uLong nNd)77 SwHistorySetFmt::SwHistorySetFmt( const SfxPoolItem* pFmtHt, sal_uLong nNd )
78 : SwHistoryHint( HSTRY_SETFMTHNT )
79 , m_pAttr( pFmtHt->Clone() )
80 , m_nNodeIndex( nNd )
81 {
82 switch ( m_pAttr->Which() )
83 {
84 case RES_PAGEDESC:
85 static_cast<SwFmtPageDesc&>(*m_pAttr).ChgDefinedIn( 0 );
86 break;
87 case RES_PARATR_DROP:
88 static_cast<SwFmtDrop&>(*m_pAttr).ChgDefinedIn( 0 );
89 break;
90 case RES_BOXATR_FORMULA:
91 {
92 //JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
93 SwTblBoxFormula& rNew = static_cast<SwTblBoxFormula&>(*m_pAttr);
94 if ( rNew.IsIntrnlName() )
95 {
96 const SwTblBoxFormula& rOld =
97 *static_cast<const SwTblBoxFormula*>(pFmtHt);
98 const SwNode* pNd = rOld.GetNodeOfFormula();
99 if ( pNd )
100 {
101 const SwTableNode* pTableNode = pNd->FindTableNode();
102 if (pTableNode)
103 {
104 SwTableFmlUpdate aMsgHnt( &pTableNode->GetTable() );
105 aMsgHnt.eFlags = TBL_BOXNAME;
106 rNew.ChgDefinedIn( rOld.GetDefinedIn() );
107 rNew.ChangeState( &aMsgHnt );
108 }
109 }
110 }
111 rNew.ChgDefinedIn( 0 );
112 }
113 break;
114 }
115 }
116
GetDescription() const117 String SwHistorySetFmt::GetDescription() const
118 {
119 String aResult ;
120
121 sal_uInt16 nWhich = m_pAttr->Which();
122 switch (nWhich)
123 {
124 case RES_BREAK:
125 switch ((static_cast<SvxFmtBreakItem &>(*m_pAttr)).GetBreak())
126 {
127 case SVX_BREAK_PAGE_BEFORE:
128 case SVX_BREAK_PAGE_AFTER:
129 case SVX_BREAK_PAGE_BOTH:
130 aResult = SW_RES(STR_UNDO_PAGEBREAKS);
131
132 break;
133 case SVX_BREAK_COLUMN_BEFORE:
134 case SVX_BREAK_COLUMN_AFTER:
135 case SVX_BREAK_COLUMN_BOTH:
136 aResult = SW_RES(STR_UNDO_COLBRKS);
137
138 break;
139 default:
140 break;
141 }
142 break;
143 default:
144 break;
145 }
146
147 return aResult;
148 }
149
SetInDoc(SwDoc * pDoc,bool bTmpSet)150 void SwHistorySetFmt::SetInDoc( SwDoc* pDoc, bool bTmpSet )
151 {
152 SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
153 if ( pNode->IsCntntNode() )
154 {
155 static_cast<SwCntntNode*>(pNode)->SetAttr( *m_pAttr );
156 }
157 else if ( pNode->IsTableNode() )
158 {
159 static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt()->SetFmtAttr(
160 *m_pAttr );
161 }
162 else if ( pNode->IsStartNode() && (SwTableBoxStartNode ==
163 static_cast<SwStartNode*>(pNode)->GetStartNodeType()) )
164 {
165 SwTableNode* pTNd = pNode->FindTableNode();
166 if ( pTNd )
167 {
168 SwTableBox* pBox = pTNd->GetTable().GetTblBox( m_nNodeIndex );
169 if (pBox)
170 {
171 pBox->ClaimFrmFmt()->SetFmtAttr( *m_pAttr );
172 }
173 }
174 }
175
176 if ( !bTmpSet )
177 {
178 m_pAttr.reset();
179 }
180 }
181
~SwHistorySetFmt()182 SwHistorySetFmt::~SwHistorySetFmt()
183 {
184 }
185
186
187 // --> OD 2008-02-27 #refactorlists# - removed <rDoc>
SwHistoryResetFmt(const SfxPoolItem * pFmtHt,sal_uLong nNodeIdx)188 SwHistoryResetFmt::SwHistoryResetFmt(const SfxPoolItem* pFmtHt, sal_uLong nNodeIdx)
189 // <--
190 : SwHistoryHint( HSTRY_RESETFMTHNT )
191 , m_nNodeIndex( nNodeIdx )
192 , m_nWhich( pFmtHt->Which() )
193 {
194 }
195
196
SetInDoc(SwDoc * pDoc,bool)197 void SwHistoryResetFmt::SetInDoc( SwDoc* pDoc, bool )
198 {
199 SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
200 if ( pNode->IsCntntNode() )
201 {
202 static_cast<SwCntntNode*>(pNode)->ResetAttr( m_nWhich );
203 }
204 else if ( pNode->IsTableNode() )
205 {
206 static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt()->
207 ResetFmtAttr( m_nWhich );
208 }
209 }
210
211
SwHistorySetTxt(SwTxtAttr * pTxtHt,sal_uLong nNodePos)212 SwHistorySetTxt::SwHistorySetTxt( SwTxtAttr* pTxtHt, sal_uLong nNodePos )
213 : SwHistoryHint( HSTRY_SETTXTHNT )
214 , m_nNodeIndex( nNodePos )
215 , m_nStart( *pTxtHt->GetStart() )
216 , m_nEnd( *pTxtHt->GetAnyEnd() )
217 {
218 // !! Achtung: folgende Attribute erzeugen keine FormatAttribute:
219 // - NoLineBreak, NoHypen, Inserted, Deleted
220 // Dafuer muessen Sonderbehandlungen gemacht werden !!!
221
222 // ein bisschen kompliziert, aber ist Ok so: erst vom default
223 // eine Kopie und dann die Werte aus dem Text Attribut zuweisen
224 sal_uInt16 nWhich = pTxtHt->Which();
225 if ( RES_TXTATR_CHARFMT == nWhich )
226 {
227 m_pAttr.reset( new SwFmtCharFmt( pTxtHt->GetCharFmt().GetCharFmt() ) );
228 }
229 else
230 {
231 m_pAttr.reset( pTxtHt->GetAttr().Clone() );
232 }
233 }
234
235
~SwHistorySetTxt()236 SwHistorySetTxt::~SwHistorySetTxt()
237 {
238 }
239
240
SetInDoc(SwDoc * pDoc,bool)241 void SwHistorySetTxt::SetInDoc( SwDoc* pDoc, bool )
242 {
243 if ( !m_pAttr.get() )
244 return;
245
246 if ( RES_TXTATR_CHARFMT == m_pAttr->Which() )
247 {
248 // ask the Doc if the CharFmt still exists
249 if ( USHRT_MAX == pDoc->GetCharFmts()->GetPos(
250 (static_cast<SwFmtCharFmt&>(*m_pAttr)).GetCharFmt() ) )
251 return; // do not set, format does not exist
252 }
253
254 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
255 ASSERT( pTxtNd, "SwHistorySetTxt::SetInDoc: not a TextNode" );
256
257 if ( pTxtNd )
258 {
259 pTxtNd->InsertItem( *m_pAttr, m_nStart, m_nEnd,
260 nsSetAttrMode::SETATTR_NOTXTATRCHR |
261 nsSetAttrMode::SETATTR_NOHINTADJUST );
262 }
263 }
264
265
SwHistorySetTxtFld(SwTxtFld * pTxtFld,sal_uLong nNodePos)266 SwHistorySetTxtFld::SwHistorySetTxtFld( SwTxtFld* pTxtFld, sal_uLong nNodePos )
267 : SwHistoryHint( HSTRY_SETTXTFLDHNT )
268 , m_pFldType( 0 )
269 , m_pFld( new SwFmtFld( *pTxtFld->GetFmtFld().GetField() ) )
270 {
271 // only copy if not Sys-FieldType
272 SwDoc* pDoc = pTxtFld->GetTxtNode().GetDoc();
273
274 m_nFldWhich = m_pFld->GetField()->GetTyp()->Which();
275 if (m_nFldWhich == RES_DBFLD ||
276 m_nFldWhich == RES_USERFLD ||
277 m_nFldWhich == RES_SETEXPFLD ||
278 m_nFldWhich == RES_DDEFLD ||
279 !pDoc->GetSysFldType( m_nFldWhich ))
280 {
281 m_pFldType.reset( m_pFld->GetField()->GetTyp()->Copy() );
282 m_pFld->GetField()->ChgTyp( m_pFldType.get() ); // change field type
283 }
284 m_nNodeIndex = nNodePos;
285 m_nPos = *pTxtFld->GetStart();
286 }
287
GetDescription() const288 String SwHistorySetTxtFld::GetDescription() const
289 {
290 return m_pFld->GetField()->GetDescription();;
291 }
292
~SwHistorySetTxtFld()293 SwHistorySetTxtFld::~SwHistorySetTxtFld()
294 {
295 }
296
297
SetInDoc(SwDoc * pDoc,bool)298 void SwHistorySetTxtFld::SetInDoc( SwDoc* pDoc, bool )
299 {
300 if ( !m_pFld.get() )
301 return;
302
303 SwFieldType* pNewFldType = m_pFldType.get();
304 if ( !pNewFldType )
305 {
306 pNewFldType = pDoc->GetSysFldType( m_nFldWhich );
307 }
308 else
309 {
310 // register type with the document
311 pNewFldType = pDoc->InsertFldType( *m_pFldType );
312 }
313
314 m_pFld->GetField()->ChgTyp( pNewFldType ); // change field type
315
316 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
317 ASSERT( pTxtNd, "SwHistorySetTxtFld: no TextNode" );
318
319 if ( pTxtNd )
320 {
321 pTxtNd->InsertItem( *m_pFld, m_nPos, m_nPos,
322 nsSetAttrMode::SETATTR_NOTXTATRCHR );
323 }
324 }
325
326
327
SwHistorySetRefMark(SwTxtRefMark * pTxtHt,sal_uLong nNodePos)328 SwHistorySetRefMark::SwHistorySetRefMark( SwTxtRefMark* pTxtHt, sal_uLong nNodePos )
329 : SwHistoryHint( HSTRY_SETREFMARKHNT )
330 , m_RefName( pTxtHt->GetRefMark().GetRefName() )
331 , m_nNodeIndex( nNodePos )
332 , m_nStart( *pTxtHt->GetStart() )
333 , m_nEnd( *pTxtHt->GetAnyEnd() )
334 {
335 }
336
337
SetInDoc(SwDoc * pDoc,bool)338 void SwHistorySetRefMark::SetInDoc( SwDoc* pDoc, bool )
339 {
340 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
341 ASSERT( pTxtNd, "SwHistorySetRefMark: no TextNode" );
342 if ( !pTxtNd )
343 return;
344
345 SwFmtRefMark aRefMark( m_RefName );
346
347 // if a reference mark without an end already exists here: must not insert!
348 if ( m_nStart != m_nEnd ||
349 !pTxtNd->GetTxtAttrForCharAt( m_nStart, RES_TXTATR_REFMARK ) )
350 {
351 pTxtNd->InsertItem( aRefMark, m_nStart, m_nEnd,
352 nsSetAttrMode::SETATTR_NOTXTATRCHR );
353 }
354 }
355
356
SwHistorySetTOXMark(SwTxtTOXMark * pTxtHt,sal_uLong nNodePos)357 SwHistorySetTOXMark::SwHistorySetTOXMark( SwTxtTOXMark* pTxtHt, sal_uLong nNodePos )
358 : SwHistoryHint( HSTRY_SETTOXMARKHNT )
359 , m_TOXMark( pTxtHt->GetTOXMark() )
360 , m_TOXName( m_TOXMark.GetTOXType()->GetTypeName() )
361 , m_eTOXTypes( m_TOXMark.GetTOXType()->GetType() )
362 , m_nNodeIndex( nNodePos )
363 , m_nStart( *pTxtHt->GetStart() )
364 , m_nEnd( *pTxtHt->GetAnyEnd() )
365 {
366 m_TOXMark.DeRegister();
367 }
368
369
SetInDoc(SwDoc * pDoc,bool)370 void SwHistorySetTOXMark::SetInDoc( SwDoc* pDoc, bool )
371 {
372 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
373 ASSERT( pTxtNd, "SwHistorySetTOXMark: no TextNode" );
374 if ( !pTxtNd )
375 return;
376
377 // search for respective TOX type
378 sal_uInt16 nCnt = pDoc->GetTOXTypeCount( m_eTOXTypes );
379 SwTOXType* pToxType = 0;
380 for ( sal_uInt16 n = 0; n < nCnt; ++n )
381 {
382 pToxType = const_cast<SwTOXType*>(pDoc->GetTOXType( m_eTOXTypes, n ));
383 if ( pToxType->GetTypeName() == m_TOXName )
384 break;
385 pToxType = 0;
386 }
387
388 if ( !pToxType ) // TOX type not found, create new
389 {
390 pToxType = const_cast<SwTOXType*>(
391 pDoc->InsertTOXType( SwTOXType( m_eTOXTypes, m_TOXName )));
392 }
393
394 SwTOXMark aNew( m_TOXMark );
395 aNew.RegisterToTOXType( *pToxType );
396
397 pTxtNd->InsertItem( aNew, m_nStart, m_nEnd,
398 nsSetAttrMode::SETATTR_NOTXTATRCHR );
399 }
400
401
IsEqual(const SwTOXMark & rCmp) const402 int SwHistorySetTOXMark::IsEqual( const SwTOXMark& rCmp ) const
403 {
404 return m_TOXName == rCmp.GetTOXType()->GetTypeName() &&
405 m_eTOXTypes == rCmp.GetTOXType()->GetType() &&
406 m_TOXMark.GetAlternativeText() == rCmp.GetAlternativeText() &&
407 ( (TOX_INDEX == m_eTOXTypes)
408 ? ( m_TOXMark.GetPrimaryKey() == rCmp.GetPrimaryKey() &&
409 m_TOXMark.GetSecondaryKey() == rCmp.GetSecondaryKey() )
410 : m_TOXMark.GetLevel() == rCmp.GetLevel()
411 );
412 }
413
414
SwHistoryResetTxt(sal_uInt16 nWhich,xub_StrLen nAttrStart,xub_StrLen nAttrEnd,sal_uLong nNodePos)415 SwHistoryResetTxt::SwHistoryResetTxt( sal_uInt16 nWhich,
416 xub_StrLen nAttrStart, xub_StrLen nAttrEnd, sal_uLong nNodePos )
417 : SwHistoryHint( HSTRY_RESETTXTHNT )
418 , m_nNodeIndex( nNodePos ), m_nStart( nAttrStart ), m_nEnd( nAttrEnd )
419 , m_nAttr( nWhich )
420 {
421 }
422
423
SetInDoc(SwDoc * pDoc,bool)424 void SwHistoryResetTxt::SetInDoc( SwDoc* pDoc, bool )
425 {
426 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
427 ASSERT( pTxtNd, "SwHistoryResetTxt: no TextNode" );
428 if ( pTxtNd )
429 {
430 pTxtNd->DeleteAttributes( m_nAttr, m_nStart, m_nEnd );
431 }
432 }
433
434
SwHistorySetFootnote(SwTxtFtn * pTxtFtn,sal_uLong nNodePos)435 SwHistorySetFootnote::SwHistorySetFootnote( SwTxtFtn* pTxtFtn, sal_uLong nNodePos )
436 : SwHistoryHint( HSTRY_SETFTNHNT )
437 , m_pUndo( new SwUndoSaveSection )
438 , m_FootnoteNumber( pTxtFtn->GetFtn().GetNumStr() )
439 , m_nNodeIndex( nNodePos )
440 , m_nStart( *pTxtFtn->GetStart() )
441 , m_bEndNote( pTxtFtn->GetFtn().IsEndNote() )
442 {
443 ASSERT( pTxtFtn->GetStartNode(),
444 "SwHistorySetFootnote: Footnote without Section" );
445
446 // merke die alte NodePos, denn wer weiss was alles in der SaveSection
447 // gespeichert (geloescht) wird
448 SwDoc* pDoc = const_cast<SwDoc*>(pTxtFtn->GetTxtNode().GetDoc());
449 SwNode* pSaveNd = pDoc->GetNodes()[ m_nNodeIndex ];
450
451 //Pointer auf StartNode der FtnSection merken und erstmal den Pointer im
452 //Attribut zuruecksetzen -> Damit werden automatisch die Frms vernichtet.
453 SwNodeIndex aSttIdx( *pTxtFtn->GetStartNode() );
454 pTxtFtn->SetStartNode( 0, sal_False );
455
456 m_pUndo->SaveSection( pDoc, aSttIdx );
457 m_nNodeIndex = pSaveNd->GetIndex();
458 }
459
SwHistorySetFootnote(const SwTxtFtn & rTxtFtn)460 SwHistorySetFootnote::SwHistorySetFootnote( const SwTxtFtn &rTxtFtn )
461 : SwHistoryHint( HSTRY_SETFTNHNT )
462 , m_pUndo( 0 )
463 , m_FootnoteNumber( rTxtFtn.GetFtn().GetNumStr() )
464 , m_nNodeIndex( _SwTxtFtn_GetIndex( (&rTxtFtn) ) )
465 , m_nStart( *rTxtFtn.GetStart() )
466 , m_bEndNote( rTxtFtn.GetFtn().IsEndNote() )
467 {
468 ASSERT( rTxtFtn.GetStartNode(),
469 "SwHistorySetFootnote: Footnote without Section" );
470 }
471
GetDescription() const472 String SwHistorySetFootnote::GetDescription() const
473 {
474 return SW_RES(STR_FOOTNOTE);
475 }
476
~SwHistorySetFootnote()477 SwHistorySetFootnote::~SwHistorySetFootnote()
478 {
479 }
480
481
SetInDoc(SwDoc * pDoc,bool)482 void SwHistorySetFootnote::SetInDoc( SwDoc* pDoc, bool )
483 {
484 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
485 ASSERT( pTxtNd, "SwHistorySetFootnote: no TextNode" );
486 if ( !pTxtNd )
487 return;
488
489 if ( m_pUndo.get() )
490 {
491 // set the footnote in the TextNode
492 SwFmtFtn aTemp( m_bEndNote );
493 SwFmtFtn& rNew = const_cast<SwFmtFtn&>(
494 static_cast<const SwFmtFtn&>(pDoc->GetAttrPool().Put(aTemp)) );
495 if ( m_FootnoteNumber.Len() )
496 {
497 rNew.SetNumStr( m_FootnoteNumber );
498 }
499 SwTxtFtn* pTxtFtn = new SwTxtFtn( rNew, m_nStart );
500
501 // create the section of the Footnote
502 SwNodeIndex aIdx( *pTxtNd );
503 m_pUndo->RestoreSection( pDoc, &aIdx, SwFootnoteStartNode );
504 pTxtFtn->SetStartNode( &aIdx );
505 if ( m_pUndo->GetHistory() )
506 {
507 // create frames only now
508 m_pUndo->GetHistory()->Rollback( pDoc );
509 }
510
511 pTxtNd->InsertHint( pTxtFtn );
512 }
513 else
514 {
515 SwTxtFtn * const pFtn =
516 const_cast<SwTxtFtn*>( static_cast<const SwTxtFtn*>(
517 pTxtNd->GetTxtAttrForCharAt( m_nStart )));
518 SwFmtFtn &rFtn = const_cast<SwFmtFtn&>(pFtn->GetFtn());
519 rFtn.SetNumStr( m_FootnoteNumber );
520 if ( rFtn.IsEndNote() != m_bEndNote )
521 {
522 rFtn.SetEndNote( m_bEndNote );
523 pFtn->CheckCondColl();
524 }
525 }
526 }
527
528
SwHistoryChangeFmtColl(SwFmtColl * pFmtColl,sal_uLong nNd,sal_uInt8 nNodeWhich)529 SwHistoryChangeFmtColl::SwHistoryChangeFmtColl( SwFmtColl* pFmtColl, sal_uLong nNd,
530 sal_uInt8 nNodeWhich )
531 : SwHistoryHint( HSTRY_CHGFMTCOLL )
532 , m_pColl( pFmtColl )
533 , m_nNodeIndex( nNd )
534 , m_nNodeType( nNodeWhich )
535 {
536 }
537
SetInDoc(SwDoc * pDoc,bool)538 void SwHistoryChangeFmtColl::SetInDoc( SwDoc* pDoc, bool )
539 {
540 SwCntntNode * pCntntNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetCntntNode();
541 ASSERT( pCntntNd, "SwHistoryChangeFmtColl: no ContentNode" );
542
543 // before setting the format, check if it is still available in the
544 // document. if it has been deleted, there is no undo!
545 if ( pCntntNd && m_nNodeType == pCntntNd->GetNodeType() )
546 {
547 if ( ND_TEXTNODE == m_nNodeType )
548 {
549 if ( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos(
550 static_cast<SwTxtFmtColl * const>(m_pColl) ))
551 {
552 pCntntNd->ChgFmtColl( m_pColl );
553 }
554 }
555 else if ( USHRT_MAX != pDoc->GetGrfFmtColls()->GetPos(
556 static_cast<SwGrfFmtColl * const>(m_pColl) ))
557 {
558 pCntntNd->ChgFmtColl( m_pColl );
559 }
560 }
561 }
562
563
SwHistoryTxtFlyCnt(SwFrmFmt * const pFlyFmt)564 SwHistoryTxtFlyCnt::SwHistoryTxtFlyCnt( SwFrmFmt* const pFlyFmt )
565 : SwHistoryHint( HSTRY_FLYCNT )
566 , m_pUndo( new SwUndoDelLayFmt( pFlyFmt ) )
567 {
568 ASSERT( pFlyFmt, "SwHistoryTxtFlyCnt: no Format" );
569 m_pUndo->ChgShowSel( sal_False );
570 }
571
572
~SwHistoryTxtFlyCnt()573 SwHistoryTxtFlyCnt::~SwHistoryTxtFlyCnt()
574 {
575 }
576
577
SetInDoc(SwDoc * pDoc,bool)578 void SwHistoryTxtFlyCnt::SetInDoc( SwDoc* pDoc, bool )
579 {
580 ::sw::IShellCursorSupplier *const pISCS(pDoc->GetIShellCursorSupplier());
581 OSL_ASSERT(pISCS);
582 ::sw::UndoRedoContext context(*pDoc, *pISCS);
583 m_pUndo->UndoImpl(context);
584 }
585
586
587
SwHistoryBookmark(const::sw::mark::IMark & rBkmk,bool bSavePos,bool bSaveOtherPos)588 SwHistoryBookmark::SwHistoryBookmark(
589 const ::sw::mark::IMark& rBkmk,
590 bool bSavePos,
591 bool bSaveOtherPos)
592 : SwHistoryHint(HSTRY_BOOKMARK)
593 , m_aName(rBkmk.GetName())
594 , m_aShortName()
595 , m_aKeycode()
596 , m_nNode(bSavePos ?
597 rBkmk.GetMarkPos().nNode.GetIndex() : 0)
598 , m_nOtherNode(bSaveOtherPos ?
599 rBkmk.GetOtherMarkPos().nNode.GetIndex() : 0)
600 , m_nCntnt(bSavePos ?
601 rBkmk.GetMarkPos().nContent.GetIndex() : 0)
602 , m_nOtherCntnt(bSaveOtherPos ?
603 rBkmk.GetOtherMarkPos().nContent.GetIndex() :0)
604 , m_bSavePos(bSavePos)
605 , m_bSaveOtherPos(bSaveOtherPos)
606 , m_bHadOtherPos(rBkmk.IsExpanded())
607 , m_eBkmkType(IDocumentMarkAccess::GetType(rBkmk))
608 {
609 const ::sw::mark::IBookmark* const pBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(&rBkmk);
610 if(pBookmark)
611 {
612 m_aKeycode = pBookmark->GetKeyCode();
613 m_aShortName = pBookmark->GetShortName();
614
615 ::sfx2::Metadatable const*const pMetadatable(
616 dynamic_cast< ::sfx2::Metadatable const* >(pBookmark));
617 if (pMetadatable)
618 {
619 m_pMetadataUndo = pMetadatable->CreateUndo();
620 }
621 }
622 }
623
624
SetInDoc(SwDoc * pDoc,bool)625 void SwHistoryBookmark::SetInDoc( SwDoc* pDoc, bool )
626 {
627 ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
628
629 SwNodes& rNds = pDoc->GetNodes();
630 IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
631 ::std::auto_ptr<SwPaM> pPam;
632 ::sw::mark::IMark* pMark = NULL;
633
634 if(m_bSavePos)
635 {
636 SwCntntNode* const pCntntNd = rNds[m_nNode]->GetCntntNode();
637 OSL_ENSURE(pCntntNd,
638 "<SwHistoryBookmark::SetInDoc(..)>"
639 " - wrong node for a mark");
640
641 // #111660# don't crash when nNode1 doesn't point to content node.
642 if(pCntntNd)
643 pPam = ::std::auto_ptr<SwPaM>(new SwPaM(*pCntntNd, m_nCntnt));
644 }
645 else
646 {
647 pMark = pMarkAccess->findMark(m_aName)->get();
648 pPam = ::std::auto_ptr<SwPaM>(new SwPaM(pMark->GetMarkPos()));
649 }
650
651 if(m_bSaveOtherPos)
652 {
653 SwCntntNode* const pCntntNd = rNds[m_nOtherNode]->GetCntntNode();
654 OSL_ENSURE(pCntntNd,
655 "<SwHistoryBookmark::SetInDoc(..)>"
656 " - wrong node for a mark");
657
658 if(pPam.get() != NULL && pCntntNd)
659 {
660 pPam->SetMark();
661 pPam->GetMark()->nNode = m_nOtherNode;
662 pPam->GetMark()->nContent.Assign(pCntntNd, m_nOtherCntnt);
663 }
664 }
665 else if(m_bHadOtherPos)
666 {
667 if(!pMark)
668 pMark = pMarkAccess->findMark(m_aName)->get();
669 OSL_ENSURE(pMark->IsExpanded(),
670 "<SwHistoryBookmark::SetInDoc(..)>"
671 " - missing pos on old mark");
672 pPam->SetMark();
673 *pPam->GetMark() = pMark->GetOtherMarkPos();
674 }
675
676 if(pPam.get())
677 {
678 if ( pMark != NULL )
679 {
680 pMarkAccess->deleteMark( pMark );
681 }
682 ::sw::mark::IBookmark* const pBookmark =
683 dynamic_cast< ::sw::mark::IBookmark* >( pMarkAccess->makeMark(*pPam, m_aName, m_eBkmkType) );
684 if ( pBookmark != NULL )
685 {
686 pBookmark->SetKeyCode(m_aKeycode);
687 pBookmark->SetShortName(m_aShortName);
688 if (m_pMetadataUndo)
689 {
690 ::sfx2::Metadatable * const pMeta(
691 dynamic_cast< ::sfx2::Metadatable* >(pBookmark));
692 OSL_ENSURE(pMeta, "metadata undo, but not metadatable?");
693 if (pMeta)
694 {
695 pMeta->RestoreMetadata(m_pMetadataUndo);
696 }
697 }
698 }
699 }
700 }
701
702
IsEqualBookmark(const::sw::mark::IMark & rBkmk)703 bool SwHistoryBookmark::IsEqualBookmark(const ::sw::mark::IMark& rBkmk)
704 {
705 return m_nNode == rBkmk.GetMarkPos().nNode.GetIndex()
706 && m_nCntnt == rBkmk.GetMarkPos().nContent.GetIndex()
707 && m_aName == rBkmk.GetName();
708 }
709
GetName() const710 const ::rtl::OUString& SwHistoryBookmark::GetName() const
711 {
712 return m_aName;
713 }
714
715 /*************************************************************************/
716
717
SwHistorySetAttrSet(const SfxItemSet & rSet,sal_uLong nNodePos,const SvUShortsSort & rSetArr)718 SwHistorySetAttrSet::SwHistorySetAttrSet( const SfxItemSet& rSet,
719 sal_uLong nNodePos, const SvUShortsSort& rSetArr )
720 : SwHistoryHint( HSTRY_SETATTRSET )
721 , m_OldSet( rSet )
722 , m_ResetArray( 0, 4 )
723 , m_nNodeIndex( nNodePos )
724 {
725 SfxItemIter aIter( m_OldSet ), aOrigIter( rSet );
726 const SfxPoolItem* pItem = aIter.FirstItem(),
727 * pOrigItem = aOrigIter.FirstItem();
728 do {
729 if( !rSetArr.Seek_Entry( pOrigItem->Which() ))
730 {
731 m_ResetArray.Insert( pOrigItem->Which(), m_ResetArray.Count() );
732 m_OldSet.ClearItem( pOrigItem->Which() );
733 }
734 else
735 {
736 switch ( pItem->Which() )
737 {
738 case RES_PAGEDESC:
739 static_cast<SwFmtPageDesc*>(
740 const_cast<SfxPoolItem*>(pItem))->ChgDefinedIn( 0 );
741 break;
742
743 case RES_PARATR_DROP:
744 static_cast<SwFmtDrop*>(
745 const_cast<SfxPoolItem*>(pItem))->ChgDefinedIn( 0 );
746 break;
747
748 case RES_BOXATR_FORMULA:
749 {
750 //JP 20.04.98: Bug 49502 - wenn eine Formel gesetzt ist, nie den
751 // Value mit sichern. Der muss gegebenfalls neu
752 // errechnet werden!
753 //JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
754 m_OldSet.ClearItem( RES_BOXATR_VALUE );
755
756 SwTblBoxFormula& rNew =
757 *static_cast<SwTblBoxFormula*>(
758 const_cast<SfxPoolItem*>(pItem));
759 if ( rNew.IsIntrnlName() )
760 {
761 const SwTblBoxFormula& rOld =
762 static_cast<const SwTblBoxFormula&>(
763 rSet.Get( RES_BOXATR_FORMULA ));
764 const SwNode* pNd = rOld.GetNodeOfFormula();
765 if ( pNd )
766 {
767 const SwTableNode* pTableNode
768 = pNd->FindTableNode();
769 if (pTableNode)
770 {
771 SwTableFmlUpdate aMsgHnt(
772 &pTableNode->GetTable() );
773 aMsgHnt.eFlags = TBL_BOXNAME;
774 rNew.ChgDefinedIn( rOld.GetDefinedIn() );
775 rNew.ChangeState( &aMsgHnt );
776 }
777 }
778 }
779 rNew.ChgDefinedIn( 0 );
780 }
781 break;
782 }
783 }
784
785 if( aIter.IsAtEnd() )
786 break;
787 pItem = aIter.NextItem();
788 pOrigItem = aOrigIter.NextItem();
789 } while( sal_True );
790 }
791
SetInDoc(SwDoc * pDoc,bool)792 void SwHistorySetAttrSet::SetInDoc( SwDoc* pDoc, bool )
793 {
794 ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
795
796 SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
797 if ( pNode->IsCntntNode() )
798 {
799 static_cast<SwCntntNode*>(pNode)->SetAttr( m_OldSet );
800 if ( m_ResetArray.Count() )
801 {
802 static_cast<SwCntntNode*>(pNode)->ResetAttr( m_ResetArray );
803 }
804 }
805 else if ( pNode->IsTableNode() )
806 {
807 SwFmt& rFmt =
808 *static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt();
809 rFmt.SetFmtAttr( m_OldSet );
810 if ( m_ResetArray.Count() )
811 {
812 rFmt.ResetFmtAttr( *m_ResetArray.GetData() );
813 }
814 }
815 }
816
817 /*************************************************************************/
818
819
SwHistoryResetAttrSet(const SfxItemSet & rSet,sal_uLong nNodePos,xub_StrLen nAttrStt,xub_StrLen nAttrEnd)820 SwHistoryResetAttrSet::SwHistoryResetAttrSet( const SfxItemSet& rSet,
821 sal_uLong nNodePos, xub_StrLen nAttrStt, xub_StrLen nAttrEnd )
822 : SwHistoryHint( HSTRY_RESETATTRSET )
823 , m_nNodeIndex( nNodePos ), m_nStart( nAttrStt ), m_nEnd( nAttrEnd )
824 , m_Array( (sal_uInt8)rSet.Count() )
825 {
826 SfxItemIter aIter( rSet );
827 bool bAutoStyle = false;
828
829 while( sal_True )
830 {
831 const sal_uInt16 nWhich = aIter.GetCurItem()->Which();
832
833 #ifndef PRODUCT
834 switch (nWhich)
835 {
836 case RES_TXTATR_REFMARK:
837 case RES_TXTATR_TOXMARK:
838 if (m_nStart != m_nEnd) break; // else: fall through!
839 case RES_TXTATR_FIELD:
840 case RES_TXTATR_ANNOTATION:
841 case RES_TXTATR_FLYCNT:
842 case RES_TXTATR_FTN:
843 case RES_TXTATR_META:
844 case RES_TXTATR_METAFIELD:
845 ASSERT(rSet.Count() == 1,
846 "text attribute with CH_TXTATR, but not the only one:"
847 "\nnot such a good idea");
848 break;
849 }
850 #endif
851
852 // Character attribute cannot be inserted into the hints array
853 // anymore. Therefore we have to treat them as one RES_TXTATR_AUTOFMT:
854 if (isCHRATR(nWhich))
855 {
856 bAutoStyle = true;
857 }
858 else
859 {
860 m_Array.Insert( aIter.GetCurItem()->Which(), m_Array.Count() );
861 }
862
863 if( aIter.IsAtEnd() )
864 break;
865
866 aIter.NextItem();
867 }
868
869 if ( bAutoStyle )
870 {
871 m_Array.Insert( RES_TXTATR_AUTOFMT, m_Array.Count() );
872 }
873 }
874
875
SetInDoc(SwDoc * pDoc,bool)876 void SwHistoryResetAttrSet::SetInDoc( SwDoc* pDoc, bool )
877 {
878 ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
879
880 SwCntntNode * pCntntNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetCntntNode();
881 ASSERT( pCntntNd, "SwHistoryResetAttrSet: no CntntNode" );
882
883 if (pCntntNd)
884 {
885 const sal_uInt16* pArr = m_Array.GetData();
886 if ( USHRT_MAX == m_nEnd && USHRT_MAX == m_nStart )
887 {
888 // no area: use ContentNode
889 for ( sal_uInt16 n = m_Array.Count(); n; --n, ++pArr )
890 {
891 pCntntNd->ResetAttr( *pArr );
892 }
893 }
894 else
895 {
896 // area: use TextNode
897 for ( sal_uInt16 n = m_Array.Count(); n; --n, ++pArr )
898 {
899 static_cast<SwTxtNode*>(pCntntNd)->
900 DeleteAttributes( *pArr, m_nStart, m_nEnd );
901 }
902 }
903 }
904 }
905
906
907 /*************************************************************************/
908
909
SwHistoryChangeFlyAnchor(SwFrmFmt & rFmt)910 SwHistoryChangeFlyAnchor::SwHistoryChangeFlyAnchor( SwFrmFmt& rFmt )
911 : SwHistoryHint( HSTRY_CHGFLYANCHOR )
912 , m_rFmt( rFmt )
913 , m_nOldNodeIndex( rFmt.GetAnchor().GetCntntAnchor()->nNode.GetIndex() )
914 , m_nOldContentIndex( (FLY_AT_CHAR == rFmt.GetAnchor().GetAnchorId())
915 ? rFmt.GetAnchor().GetCntntAnchor()->nContent.GetIndex()
916 : STRING_MAXLEN )
917 {
918 }
919
920
SetInDoc(SwDoc * pDoc,bool)921 void SwHistoryChangeFlyAnchor::SetInDoc( SwDoc* pDoc, bool )
922 {
923 ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
924
925 sal_uInt16 nPos = pDoc->GetSpzFrmFmts()->GetPos( &m_rFmt );
926 if ( USHRT_MAX != nPos ) // Format does still exist
927 {
928 SwFmtAnchor aTmp( m_rFmt.GetAnchor() );
929
930 SwNode* pNd = pDoc->GetNodes()[ m_nOldNodeIndex ];
931 SwCntntNode* pCNd = pNd->GetCntntNode();
932 SwPosition aPos( *pNd );
933 if ( STRING_MAXLEN != m_nOldContentIndex )
934 {
935 ASSERT(pCNd, "SwHistoryChangeFlyAnchor: no ContentNode");
936 if (pCNd)
937 {
938 aPos.nContent.Assign( pCNd, m_nOldContentIndex );
939 }
940 }
941 aTmp.SetAnchor( &aPos );
942
943 // so the Layout does not get confused
944 if ( !pCNd || !pCNd->getLayoutFrm( pDoc->GetCurrentLayout(), 0, 0, sal_False ) )
945 {
946 m_rFmt.DelFrms();
947 }
948
949 m_rFmt.SetFmtAttr( aTmp );
950 }
951 }
952
953
954 /*************************************************************************/
955
SwHistoryChangeFlyChain(SwFlyFrmFmt & rFmt,const SwFmtChain & rAttr)956 SwHistoryChangeFlyChain::SwHistoryChangeFlyChain( SwFlyFrmFmt& rFmt,
957 const SwFmtChain& rAttr )
958 : SwHistoryHint( HSTRY_CHGFLYCHAIN )
959 , m_pPrevFmt( rAttr.GetPrev() )
960 , m_pNextFmt( rAttr.GetNext() )
961 , m_pFlyFmt( &rFmt )
962 {
963 }
964
965
SetInDoc(SwDoc * pDoc,bool)966 void SwHistoryChangeFlyChain::SetInDoc( SwDoc* pDoc, bool )
967 {
968 if ( USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pFlyFmt ) )
969 {
970 SwFmtChain aChain;
971
972 if ( m_pPrevFmt &&
973 USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pPrevFmt ) )
974 {
975 aChain.SetPrev( m_pPrevFmt );
976 SwFmtChain aTmp( m_pPrevFmt->GetChain() );
977 aTmp.SetNext( m_pFlyFmt );
978 m_pPrevFmt->SetFmtAttr( aTmp );
979 }
980
981 if ( m_pNextFmt &&
982 USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pNextFmt ) )
983 {
984 aChain.SetNext( m_pNextFmt );
985 SwFmtChain aTmp( m_pNextFmt->GetChain() );
986 aTmp.SetPrev( m_pFlyFmt );
987 m_pNextFmt->SetFmtAttr( aTmp );
988 }
989
990 if ( aChain.GetNext() || aChain.GetPrev() )
991 {
992 m_pFlyFmt->SetFmtAttr( aChain );
993 }
994 }
995 }
996
997
998 // -> #i27615#
SwHistoryChangeCharFmt(const SfxItemSet & rSet,const String & sFmt)999 SwHistoryChangeCharFmt::SwHistoryChangeCharFmt(const SfxItemSet & rSet,
1000 const String & sFmt)
1001 : SwHistoryHint(HSTRY_CHGCHARFMT)
1002 , m_OldSet(rSet), m_Fmt(sFmt)
1003 {
1004 }
1005
SetInDoc(SwDoc * pDoc,bool)1006 void SwHistoryChangeCharFmt::SetInDoc(SwDoc * pDoc, bool )
1007 {
1008 SwCharFmt * pCharFmt = pDoc->FindCharFmtByName(m_Fmt);
1009
1010 if (pCharFmt)
1011 {
1012 pCharFmt->SetFmtAttr(m_OldSet);
1013 }
1014 }
1015 // <- #i27615#
1016
1017 /* */
1018
1019
SwHistory(sal_uInt16 nInitSz,sal_uInt16 nGrowSz)1020 SwHistory::SwHistory( sal_uInt16 nInitSz, sal_uInt16 nGrowSz )
1021 : m_SwpHstry( (sal_uInt8)nInitSz, (sal_uInt8)nGrowSz )
1022 , m_nEndDiff( 0 )
1023 {}
1024
1025
~SwHistory()1026 SwHistory::~SwHistory()
1027 {
1028 Delete( 0 );
1029 }
1030
1031
1032 /*************************************************************************
1033 |*
1034 |* void SwHistory::Add()
1035 |*
1036 |* Beschreibung Dokument 1.0
1037 |* Ersterstellung JP 18.02.91
1038 |* Letzte Aenderung JP 18.02.91
1039 |*
1040 *************************************************************************/
1041
Add(const SfxPoolItem * pOldValue,const SfxPoolItem * pNewValue,sal_uLong nNodeIdx)1042 void SwHistory::Add(
1043 const SfxPoolItem* pOldValue,
1044 const SfxPoolItem* pNewValue,
1045 sal_uLong nNodeIdx)
1046 {
1047 ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
1048 const sal_uInt16 nWhich(pNewValue->Which());
1049
1050 // excluded values
1051 if(nWhich == RES_TXTATR_FIELD || nWhich == RES_TXTATR_ANNOTATION)
1052 {
1053 return;
1054 }
1055
1056 // no default Attribute?
1057 SwHistoryHint* pHt = 0;
1058
1059 //UUUU To be able to include the DrawingLayer FillItems something more
1060 // general has to be done to check if an Item is default than to check
1061 // if it's pointzer equals that in Writer's global PoolDefaults (held in
1062 // aAttrTab and used to fill the pool defaults in Writer - looks as if
1063 // Writer is *older* than the SfxItemPool ?). I checked the possibility to
1064 // get the SfxItemPool here (works), but decided to use the SfxPoolItem's
1065 // global tooling aka IsDefaultItem(const SfxPoolItem*) for now
1066 if(pOldValue && !IsDefaultItem(pOldValue))
1067 {
1068 pHt = new SwHistorySetFmt( pOldValue, nNodeIdx );
1069 }
1070 else
1071 {
1072 pHt = new SwHistoryResetFmt( pNewValue, nNodeIdx );
1073 }
1074
1075 m_SwpHstry.Insert(pHt, Count());
1076 }
1077
1078
Add(SwTxtAttr * pHint,sal_uLong nNodeIdx,bool bNewAttr)1079 void SwHistory::Add( SwTxtAttr* pHint, sal_uLong nNodeIdx, bool bNewAttr )
1080 {
1081 ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
1082
1083 SwHistoryHint * pHt;
1084 sal_uInt16 nAttrWhich = pHint->Which();
1085
1086 if( !bNewAttr )
1087 {
1088 switch ( nAttrWhich )
1089 {
1090 case RES_TXTATR_FTN:
1091 pHt = new SwHistorySetFootnote(
1092 static_cast<SwTxtFtn*>(pHint), nNodeIdx );
1093 break;
1094 case RES_TXTATR_FLYCNT:
1095 pHt = new SwHistoryTxtFlyCnt( static_cast<SwTxtFlyCnt*>(pHint)
1096 ->GetFlyCnt().GetFrmFmt() );
1097 break;
1098 case RES_TXTATR_FIELD:
1099 case RES_TXTATR_ANNOTATION:
1100 pHt = new SwHistorySetTxtFld(
1101 static_cast<SwTxtFld*>(pHint), nNodeIdx );
1102 break;
1103 case RES_TXTATR_TOXMARK:
1104 pHt = new SwHistorySetTOXMark(
1105 static_cast<SwTxtTOXMark*>(pHint), nNodeIdx );
1106 break;
1107 case RES_TXTATR_REFMARK:
1108 pHt = new SwHistorySetRefMark(
1109 static_cast<SwTxtRefMark*>(pHint), nNodeIdx );
1110 break;
1111 default:
1112 pHt = new SwHistorySetTxt(
1113 static_cast<SwTxtAttr*>(pHint), nNodeIdx );
1114 }
1115 }
1116 else
1117 {
1118 pHt = new SwHistoryResetTxt( pHint->Which(), *pHint->GetStart(),
1119 *pHint->GetAnyEnd(), nNodeIdx );
1120 }
1121 m_SwpHstry.Insert( pHt, Count() );
1122 }
1123
1124
Add(SwFmtColl * pColl,sal_uLong nNodeIdx,sal_uInt8 nWhichNd)1125 void SwHistory::Add( SwFmtColl* pColl, sal_uLong nNodeIdx, sal_uInt8 nWhichNd )
1126 {
1127 ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
1128
1129 SwHistoryHint * pHt =
1130 new SwHistoryChangeFmtColl( pColl, nNodeIdx, nWhichNd );
1131 m_SwpHstry.Insert( pHt, Count() );
1132 }
1133
1134
Add(const::sw::mark::IMark & rBkmk,bool bSavePos,bool bSaveOtherPos)1135 void SwHistory::Add(const ::sw::mark::IMark& rBkmk, bool bSavePos, bool bSaveOtherPos)
1136 {
1137 ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
1138
1139 SwHistoryHint * pHt = new SwHistoryBookmark(rBkmk, bSavePos, bSaveOtherPos);
1140 m_SwpHstry.Insert( pHt, Count() );
1141 }
1142
1143
Add(SwFrmFmt & rFmt)1144 void SwHistory::Add( SwFrmFmt& rFmt )
1145 {
1146 SwHistoryHint * pHt = new SwHistoryChangeFlyAnchor( rFmt );
1147 m_SwpHstry.Insert( pHt, Count() );
1148 }
1149
Add(SwFlyFrmFmt & rFmt,sal_uInt16 & rSetPos)1150 void SwHistory::Add( SwFlyFrmFmt& rFmt, sal_uInt16& rSetPos )
1151 {
1152 ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
1153
1154 SwHistoryHint * pHint;
1155 const sal_uInt16 nWh = rFmt.Which();
1156 if( RES_FLYFRMFMT == nWh || RES_DRAWFRMFMT == nWh )
1157 {
1158 pHint = new SwHistoryTxtFlyCnt( &rFmt );
1159 m_SwpHstry.Insert( pHint, Count() );
1160
1161 const SwFmtChain* pChainItem;
1162 if( SFX_ITEM_SET == rFmt.GetItemState( RES_CHAIN, sal_False,
1163 (const SfxPoolItem**)&pChainItem ))
1164 {
1165 if( pChainItem->GetNext() || pChainItem->GetPrev() )
1166 {
1167 SwHistoryHint * pHt =
1168 new SwHistoryChangeFlyChain( rFmt, *pChainItem );
1169 m_SwpHstry.Insert( pHt, rSetPos++ );
1170 if ( pChainItem->GetNext() )
1171 {
1172 SwFmtChain aTmp( pChainItem->GetNext()->GetChain() );
1173 aTmp.SetPrev( 0 );
1174 pChainItem->GetNext()->SetFmtAttr( aTmp );
1175 }
1176 if ( pChainItem->GetPrev() )
1177 {
1178 SwFmtChain aTmp( pChainItem->GetPrev()->GetChain() );
1179 aTmp.SetNext( 0 );
1180 pChainItem->GetPrev()->SetFmtAttr( aTmp );
1181 }
1182 }
1183 rFmt.ResetFmtAttr( RES_CHAIN );
1184 }
1185 }
1186 }
1187
Add(const SwTxtFtn & rFtn)1188 void SwHistory::Add( const SwTxtFtn& rFtn )
1189 {
1190 SwHistoryHint *pHt = new SwHistorySetFootnote( rFtn );
1191 m_SwpHstry.Insert( pHt, Count() );
1192 }
1193
1194 // #i27615#
Add(const SfxItemSet & rSet,const SwCharFmt & rFmt)1195 void SwHistory::Add(const SfxItemSet & rSet, const SwCharFmt & rFmt)
1196 {
1197 SwHistoryHint * pHt = new SwHistoryChangeCharFmt(rSet, rFmt.GetName());
1198 m_SwpHstry.Insert(pHt, Count());
1199 }
1200
1201 /*************************************************************************
1202 |*
1203 |* sal_Bool SwHistory::Rollback()
1204 |*
1205 |* Beschreibung Dokument 1.0
1206 |* Ersterstellung JP 18.02.91
1207 |* Letzte Aenderung JP 18.02.91
1208 |*
1209 *************************************************************************/
1210
1211
Rollback(SwDoc * pDoc,sal_uInt16 nStart)1212 bool SwHistory::Rollback( SwDoc* pDoc, sal_uInt16 nStart )
1213 {
1214 if ( !Count() )
1215 return false;
1216
1217 SwHistoryHint * pHHt;
1218 sal_uInt16 i;
1219 for ( i = Count(); i > nStart ; )
1220 {
1221 pHHt = m_SwpHstry[ --i ];
1222 pHHt->SetInDoc( pDoc, false );
1223 delete pHHt;
1224 }
1225 m_SwpHstry.Remove( nStart, Count() - nStart );
1226 m_nEndDiff = 0;
1227 return true;
1228 }
1229
1230
1231
TmpRollback(SwDoc * pDoc,sal_uInt16 nStart,bool bToFirst)1232 bool SwHistory::TmpRollback( SwDoc* pDoc, sal_uInt16 nStart, bool bToFirst )
1233 {
1234 sal_uInt16 nEnd = Count() - m_nEndDiff;
1235 if ( !Count() || !nEnd || nStart >= nEnd )
1236 return false;
1237
1238 SwHistoryHint * pHHt;
1239 if ( bToFirst )
1240 {
1241 for ( ; nEnd > nStart; ++m_nEndDiff )
1242 {
1243 pHHt = m_SwpHstry[ --nEnd ];
1244 pHHt->SetInDoc( pDoc, true );
1245 }
1246 }
1247 else
1248 {
1249 for ( ; nStart < nEnd; ++m_nEndDiff, ++nStart )
1250 {
1251 pHHt = m_SwpHstry[ nStart ];
1252 pHHt->SetInDoc( pDoc, true );
1253 }
1254 }
1255 return true;
1256 }
1257
1258
Delete(sal_uInt16 nStart)1259 void SwHistory::Delete( sal_uInt16 nStart )
1260 {
1261 for ( sal_uInt16 n = Count(); n > nStart; )
1262 {
1263 m_SwpHstry.DeleteAndDestroy( --n, 1 );
1264 }
1265 m_nEndDiff = 0;
1266 }
1267
1268
SetTmpEnd(sal_uInt16 nNewTmpEnd)1269 sal_uInt16 SwHistory::SetTmpEnd( sal_uInt16 nNewTmpEnd )
1270 {
1271 ASSERT( nNewTmpEnd <= Count(), "SwHistory::SetTmpEnd: out of bounds" );
1272
1273 sal_uInt16 nOld = Count() - m_nEndDiff;
1274 m_nEndDiff = Count() - nNewTmpEnd;
1275
1276 // for every SwHistoryFlyCnt, call the Redo of its UndoObject.
1277 // this saves the formats of the flys!
1278 for ( sal_uInt16 n = nOld; n < nNewTmpEnd; n++ )
1279 {
1280 if ( HSTRY_FLYCNT == (*this)[ n ]->Which() )
1281 {
1282 static_cast<SwHistoryTxtFlyCnt*>((*this)[ n ])
1283 ->GetUDelLFmt()->RedoForRollback();
1284 }
1285 }
1286
1287 return nOld;
1288 }
1289
CopyFmtAttr(const SfxItemSet & rSet,sal_uLong nNodeIdx)1290 void SwHistory::CopyFmtAttr(
1291 const SfxItemSet& rSet,
1292 sal_uLong nNodeIdx)
1293 {
1294 if(rSet.Count())
1295 {
1296 SfxItemIter aIter(rSet);
1297
1298 do
1299 {
1300 if(!IsInvalidItem(aIter.GetCurItem()))
1301 {
1302 const SfxPoolItem* pNew = aIter.GetCurItem();
1303
1304 Add(
1305 pNew,
1306 pNew,
1307 nNodeIdx);
1308 }
1309
1310 if(aIter.IsAtEnd())
1311 {
1312 break;
1313 }
1314
1315 aIter.NextItem();
1316
1317 } while(true);
1318 }
1319 }
1320
CopyAttr(SwpHints * pHts,const sal_uLong nNodeIdx,const xub_StrLen nStart,const xub_StrLen nEnd,const bool bCopyFields)1321 void SwHistory::CopyAttr(
1322 SwpHints* pHts,
1323 const sal_uLong nNodeIdx,
1324 const xub_StrLen nStart,
1325 const xub_StrLen nEnd,
1326 const bool bCopyFields )
1327 {
1328 if( !pHts )
1329 return;
1330
1331 // copy all attributes of the TextNode in the area from nStart to nEnd
1332 SwTxtAttr* pHt;
1333 xub_StrLen nAttrStt;
1334 const xub_StrLen * pEndIdx;
1335 for( sal_uInt16 n = 0; n < pHts->Count(); n++ )
1336 {
1337 pHt = pHts->GetTextHint(n);
1338 nAttrStt = *pHt->GetStart();
1339 if( 0 != ( pEndIdx = pHt->GetEnd() ) && nAttrStt > nEnd )
1340 break;
1341
1342 // Flys und Ftn nie kopieren !!
1343 sal_Bool bNextAttr = sal_False;
1344 switch( pHt->Which() )
1345 {
1346 case RES_TXTATR_FIELD:
1347 case RES_TXTATR_ANNOTATION:
1348 case RES_TXTATR_INPUTFIELD:
1349 if( !bCopyFields )
1350 bNextAttr = sal_True;
1351 break;
1352 case RES_TXTATR_FLYCNT:
1353 case RES_TXTATR_FTN:
1354 bNextAttr = sal_True;
1355 break;
1356 }
1357
1358 if( bNextAttr )
1359 continue;
1360
1361 // save all attributes that are somehow in this area
1362 if ( nStart <= nAttrStt )
1363 {
1364 if ( nEnd > nAttrStt )
1365 {
1366 Add( pHt, nNodeIdx, false );
1367 }
1368 }
1369 else if ( pEndIdx && nStart < *pEndIdx )
1370 {
1371 Add( pHt, nNodeIdx, false );
1372 }
1373 }
1374 }
1375
1376
1377 /*************************************************************************/
1378
1379 // Klasse zum Registrieren der History am Node, Format, HintsArray, ...
1380
SwRegHistory(SwHistory * pHst)1381 SwRegHistory::SwRegHistory( SwHistory* pHst )
1382 : SwClient( 0 )
1383 , m_pHistory( pHst )
1384 , m_nNodeIndex( ULONG_MAX )
1385 {
1386 _MakeSetWhichIds();
1387 }
1388
SwRegHistory(SwModify * pRegIn,const SwNode & rNd,SwHistory * pHst)1389 SwRegHistory::SwRegHistory( SwModify* pRegIn, const SwNode& rNd,
1390 SwHistory* pHst )
1391 : SwClient( pRegIn )
1392 , m_pHistory( pHst )
1393 , m_nNodeIndex( rNd.GetIndex() )
1394 {
1395 _MakeSetWhichIds();
1396 }
1397
SwRegHistory(const SwNode & rNd,SwHistory * pHst)1398 SwRegHistory::SwRegHistory( const SwNode& rNd, SwHistory* pHst )
1399 : SwClient( 0 )
1400 , m_pHistory( pHst )
1401 , m_nNodeIndex( rNd.GetIndex() )
1402 {
1403 _MakeSetWhichIds();
1404 }
1405
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)1406 void SwRegHistory::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
1407 {
1408 if ( m_pHistory && ( pOld || pNew ) && pOld != pNew )
1409 {
1410 if ( pNew->Which() < POOLATTR_END )
1411 {
1412 if(RES_UPDATE_ATTR == pNew->Which())
1413 {
1414 // const SfxItemPool& rPool = static_cast< const SwUpdateAttr* >(pNew)->GetSfxItemPool();
1415
1416 m_pHistory->Add(
1417 // rPool,
1418 pOld,
1419 pNew,
1420 m_nNodeIndex);
1421 }
1422 else
1423 {
1424 OSL_ENSURE(false, "Unexpected update attribute (!)");
1425 }
1426 }
1427 else if ( RES_ATTRSET_CHG == pNew->Which() )
1428 {
1429 SwHistoryHint* pNewHstr;
1430 const SfxItemSet& rSet = *static_cast< const SwAttrSetChg* >(pOld)->GetChgSet();
1431
1432 if ( 1 < rSet.Count() )
1433 {
1434 pNewHstr = new SwHistorySetAttrSet( rSet, m_nNodeIndex, m_WhichIdSet );
1435 }
1436 else
1437 {
1438 const SfxPoolItem* pItem = SfxItemIter( rSet ).FirstItem();
1439
1440 if ( m_WhichIdSet.Seek_Entry( pItem->Which() ) )
1441 {
1442 pNewHstr = new SwHistorySetFmt( pItem, m_nNodeIndex );
1443 }
1444 else
1445 {
1446 pNewHstr = new SwHistoryResetFmt( pItem, m_nNodeIndex );
1447 }
1448 }
1449
1450 m_pHistory->m_SwpHstry.Insert( pNewHstr, m_pHistory->Count() );
1451 }
1452 }
1453 }
1454
1455
1456
AddHint(SwTxtAttr * pHt,const bool bNew)1457 void SwRegHistory::AddHint( SwTxtAttr* pHt, const bool bNew )
1458 {
1459 m_pHistory->Add( pHt, m_nNodeIndex, bNew );
1460 }
1461
1462
InsertItems(const SfxItemSet & rSet,xub_StrLen const nStart,xub_StrLen const nEnd,SetAttrMode const nFlags)1463 bool SwRegHistory::InsertItems( const SfxItemSet& rSet,
1464 xub_StrLen const nStart, xub_StrLen const nEnd, SetAttrMode const nFlags )
1465 {
1466 if( !rSet.Count() )
1467 return false;
1468
1469 SwTxtNode * const pTxtNode =
1470 dynamic_cast<SwTxtNode *>(const_cast<SwModify *>(GetRegisteredIn()));
1471
1472 ASSERT(pTxtNode, "SwRegHistory not registered at text node?");
1473 if (!pTxtNode)
1474 return false;
1475
1476 if ( pTxtNode->GetpSwpHints() && m_pHistory )
1477 {
1478 pTxtNode->GetpSwpHints()->Register( this );
1479 }
1480
1481 const bool bInserted = pTxtNode->SetAttr( rSet, nStart, nEnd, nFlags );
1482
1483 // Achtung: Durch das Einfuegen eines Attributs kann das Array
1484 // geloescht werden!!! Wenn das einzufuegende zunaechst ein vorhandenes
1485 // loescht, selbst aber nicht eingefuegt werden braucht, weil die
1486 // Absatzattribute identisch sind( -> bForgetAttr in SwpHints::Insert )
1487 if ( pTxtNode->GetpSwpHints() && m_pHistory )
1488 {
1489 pTxtNode->GetpSwpHints()->DeRegister();
1490 }
1491
1492 if ( m_pHistory && bInserted )
1493 {
1494 SwHistoryHint* pNewHstr = new SwHistoryResetAttrSet( rSet,
1495 pTxtNode->GetIndex(), nStart, nEnd );
1496 // der NodeIndex kann verschoben sein !!
1497
1498 m_pHistory->m_SwpHstry.Insert( pNewHstr, m_pHistory->Count() );
1499 }
1500
1501 return bInserted;
1502 }
1503
RegisterInModify(SwModify * pRegIn,const SwNode & rNd)1504 void SwRegHistory::RegisterInModify( SwModify* pRegIn, const SwNode& rNd )
1505 {
1506 if ( m_pHistory && pRegIn )
1507 {
1508 pRegIn->Add( this );
1509 m_nNodeIndex = rNd.GetIndex();
1510 _MakeSetWhichIds();
1511 }
1512 else if ( m_WhichIdSet.Count() )
1513 {
1514 m_WhichIdSet.Remove( 0, m_WhichIdSet.Count() );
1515 }
1516 }
1517
_MakeSetWhichIds()1518 void SwRegHistory::_MakeSetWhichIds()
1519 {
1520 if (!m_pHistory) return;
1521
1522 if ( m_WhichIdSet.Count() )
1523 {
1524 m_WhichIdSet.Remove( 0, m_WhichIdSet.Count() );
1525 }
1526
1527 if( GetRegisteredIn() )
1528 {
1529 const SfxItemSet* pSet = 0;
1530 if( GetRegisteredIn()->ISA( SwCntntNode ) )
1531 {
1532 pSet = static_cast<SwCntntNode*>(
1533 const_cast<SwModify*>(GetRegisteredIn()))->GetpSwAttrSet();
1534 }
1535 else if ( GetRegisteredIn()->ISA( SwFmt ) )
1536 {
1537 pSet = &static_cast<SwFmt*>(
1538 const_cast<SwModify*>(GetRegisteredIn()))->GetAttrSet();
1539 }
1540 if( pSet && pSet->Count() )
1541 {
1542 SfxItemIter aIter( *pSet );
1543 sal_uInt16 nW = aIter.FirstItem()->Which();
1544 while( sal_True )
1545 {
1546 m_WhichIdSet.Insert( nW );
1547 if( aIter.IsAtEnd() )
1548 break;
1549 nW = aIter.NextItem()->Which();
1550 }
1551 }
1552 }
1553 }
1554
1555