update dev300-m58
[ooovba.git] / sw / source / core / undo / rolbck.cxx
blob1957c9cea3aad876c4e7b074546d37440ffab02e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: rolbck.cxx,v $
10 * $Revision: 1.24 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
36 #include <svtools/itemiter.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 <docary.hxx>
54 #include <ndtxt.hxx> // SwTxtNode
55 #include <paratr.hxx> //
56 #include <cellatr.hxx> //
57 #include <fldbas.hxx> // fuer Felder
58 #include <pam.hxx> // fuer SwPaM
59 #include <swtable.hxx>
60 #include <rolbck.hxx>
61 #include <ndgrf.hxx> // SwGrfNode
62 #include <undobj.hxx> // fuer UndoDelete
63 #include <IMark.hxx> // fuer SwBookmark
64 #include <charfmt.hxx> // #i27615#
65 #ifndef _COMCORE_HRC
66 #include <comcore.hrc>
67 #endif
68 #include <tools/resid.hxx>
69 #ifndef _UNDO_HRC
70 #include <undo.hrc>
71 #endif
72 #include <svx/brkitem.hxx>
73 #include <bookmrk.hxx>
75 SV_IMPL_PTRARR( SwpHstry, SwHistoryHintPtr)
77 String SwHistoryHint::GetDescription() const
79 return String();
83 SwHistorySetFmt::SwHistorySetFmt( const SfxPoolItem* pFmtHt, ULONG nNd )
84 : SwHistoryHint( HSTRY_SETFMTHNT )
85 , m_pAttr( pFmtHt->Clone() )
86 , m_nNodeIndex( nNd )
88 switch ( m_pAttr->Which() )
90 case RES_PAGEDESC:
91 static_cast<SwFmtPageDesc&>(*m_pAttr).ChgDefinedIn( 0 );
92 break;
93 case RES_PARATR_DROP:
94 static_cast<SwFmtDrop&>(*m_pAttr).ChgDefinedIn( 0 );
95 break;
96 case RES_BOXATR_FORMULA:
98 //JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
99 SwTblBoxFormula& rNew = static_cast<SwTblBoxFormula&>(*m_pAttr);
100 if ( rNew.IsIntrnlName() )
102 const SwTblBoxFormula& rOld =
103 *static_cast<const SwTblBoxFormula*>(pFmtHt);
104 const SwNode* pNd = rOld.GetNodeOfFormula();
105 if ( pNd )
107 const SwTableNode* pTableNode = pNd->FindTableNode();
108 if (pTableNode)
110 SwTableFmlUpdate aMsgHnt( &pTableNode->GetTable() );
111 aMsgHnt.eFlags = TBL_BOXNAME;
112 rNew.ChgDefinedIn( rOld.GetDefinedIn() );
113 rNew.ChangeState( &aMsgHnt );
117 rNew.ChgDefinedIn( 0 );
119 break;
123 String SwHistorySetFmt::GetDescription() const
125 String aResult ;
127 USHORT nWhich = m_pAttr->Which();
128 switch (nWhich)
130 case RES_BREAK:
131 switch ((static_cast<SvxFmtBreakItem &>(*m_pAttr)).GetBreak())
133 case SVX_BREAK_PAGE_BEFORE:
134 case SVX_BREAK_PAGE_AFTER:
135 case SVX_BREAK_PAGE_BOTH:
136 aResult = SW_RES(STR_UNDO_PAGEBREAKS);
138 break;
139 case SVX_BREAK_COLUMN_BEFORE:
140 case SVX_BREAK_COLUMN_AFTER:
141 case SVX_BREAK_COLUMN_BOTH:
142 aResult = SW_RES(STR_UNDO_COLBRKS);
144 break;
145 default:
146 break;
148 break;
149 default:
150 break;
153 return aResult;
156 void SwHistorySetFmt::SetInDoc( SwDoc* pDoc, bool bTmpSet )
158 SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
159 if ( pNode->IsCntntNode() )
161 static_cast<SwCntntNode*>(pNode)->SetAttr( *m_pAttr );
163 else if ( pNode->IsTableNode() )
165 static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt()->SetFmtAttr(
166 *m_pAttr );
168 else if ( pNode->IsStartNode() && (SwTableBoxStartNode ==
169 static_cast<SwStartNode*>(pNode)->GetStartNodeType()) )
171 SwTableNode* pTNd = pNode->FindTableNode();
172 if ( pTNd )
174 SwTableBox* pBox = pTNd->GetTable().GetTblBox( m_nNodeIndex );
175 if (pBox)
177 pBox->ClaimFrmFmt()->SetFmtAttr( *m_pAttr );
182 if ( !bTmpSet )
184 m_pAttr.reset();
188 SwHistorySetFmt::~SwHistorySetFmt()
193 // --> OD 2008-02-27 #refactorlists# - removed <rDoc>
194 SwHistoryResetFmt::SwHistoryResetFmt(const SfxPoolItem* pFmtHt, ULONG nNodeIdx)
195 // <--
196 : SwHistoryHint( HSTRY_RESETFMTHNT )
197 , m_nNodeIndex( nNodeIdx )
198 , m_nWhich( pFmtHt->Which() )
203 void SwHistoryResetFmt::SetInDoc( SwDoc* pDoc, bool )
205 SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
206 if ( pNode->IsCntntNode() )
208 static_cast<SwCntntNode*>(pNode)->ResetAttr( m_nWhich );
210 else if ( pNode->IsTableNode() )
212 static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt()->
213 ResetFmtAttr( m_nWhich );
218 SwHistorySetTxt::SwHistorySetTxt( SwTxtAttr* pTxtHt, ULONG nNodePos )
219 : SwHistoryHint( HSTRY_SETTXTHNT )
220 , m_nNodeIndex( nNodePos )
221 , m_nStart( *pTxtHt->GetStart() )
222 , m_nEnd( *pTxtHt->GetAnyEnd() )
224 // !! Achtung: folgende Attribute erzeugen keine FormatAttribute:
225 // - NoLineBreak, NoHypen, Inserted, Deleted
226 // Dafuer muessen Sonderbehandlungen gemacht werden !!!
228 // ein bisschen kompliziert, aber ist Ok so: erst vom default
229 // eine Kopie und dann die Werte aus dem Text Attribut zuweisen
230 USHORT nWhich = pTxtHt->Which();
231 if ( RES_TXTATR_CHARFMT == nWhich )
233 m_pAttr.reset( new SwFmtCharFmt( pTxtHt->GetCharFmt().GetCharFmt() ) );
235 else
237 m_pAttr.reset( pTxtHt->GetAttr().Clone() );
242 SwHistorySetTxt::~SwHistorySetTxt()
247 void SwHistorySetTxt::SetInDoc( SwDoc* pDoc, bool )
249 if ( !m_pAttr.get() )
250 return;
252 if ( RES_TXTATR_CHARFMT == m_pAttr->Which() )
254 // ask the Doc if the CharFmt still exists
255 if ( USHRT_MAX == pDoc->GetCharFmts()->GetPos(
256 (static_cast<SwFmtCharFmt&>(*m_pAttr)).GetCharFmt() ) )
257 return; // do not set, format does not exist
260 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
261 ASSERT( pTxtNd, "SwHistorySetTxt::SetInDoc: not a TextNode" );
263 if ( pTxtNd )
265 pTxtNd->InsertItem( *m_pAttr, m_nStart, m_nEnd,
266 nsSetAttrMode::SETATTR_NOTXTATRCHR |
267 nsSetAttrMode::SETATTR_NOHINTADJUST );
272 SwHistorySetTxtFld::SwHistorySetTxtFld( SwTxtFld* pTxtFld, ULONG nNodePos )
273 : SwHistoryHint( HSTRY_SETTXTFLDHNT )
274 , m_pFldType( 0 )
275 , m_pFld( new SwFmtFld( *pTxtFld->GetFld().GetFld() ) )
277 // only copy if not Sys-FieldType
278 SwDoc* pDoc = pTxtFld->GetTxtNode().GetDoc();
280 m_nFldWhich = m_pFld->GetFld()->GetTyp()->Which();
281 if (m_nFldWhich == RES_DBFLD ||
282 m_nFldWhich == RES_USERFLD ||
283 m_nFldWhich == RES_SETEXPFLD ||
284 m_nFldWhich == RES_DDEFLD ||
285 !pDoc->GetSysFldType( m_nFldWhich ))
287 m_pFldType.reset( m_pFld->GetFld()->GetTyp()->Copy() );
288 m_pFld->GetFld()->ChgTyp( m_pFldType.get() ); // change field type
290 m_nNodeIndex = nNodePos;
291 m_nPos = *pTxtFld->GetStart();
294 String SwHistorySetTxtFld::GetDescription() const
296 return m_pFld->GetFld()->GetDescription();;
299 SwHistorySetTxtFld::~SwHistorySetTxtFld()
304 void SwHistorySetTxtFld::SetInDoc( SwDoc* pDoc, bool )
306 if ( !m_pFld.get() )
307 return;
309 SwFieldType* pNewFldType = m_pFldType.get();
310 if ( !pNewFldType )
312 pNewFldType = pDoc->GetSysFldType( m_nFldWhich );
314 else
316 // register type with the document
317 pNewFldType = pDoc->InsertFldType( *m_pFldType );
320 m_pFld->GetFld()->ChgTyp( pNewFldType ); // change field type
322 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
323 ASSERT( pTxtNd, "SwHistorySetTxtFld: no TextNode" );
325 if ( pTxtNd )
327 pTxtNd->InsertItem( *m_pFld, m_nPos, m_nPos,
328 nsSetAttrMode::SETATTR_NOTXTATRCHR );
334 SwHistorySetRefMark::SwHistorySetRefMark( SwTxtRefMark* pTxtHt, ULONG nNodePos )
335 : SwHistoryHint( HSTRY_SETREFMARKHNT )
336 , m_RefName( pTxtHt->GetRefMark().GetRefName() )
337 , m_nNodeIndex( nNodePos )
338 , m_nStart( *pTxtHt->GetStart() )
339 , m_nEnd( *pTxtHt->GetAnyEnd() )
344 void SwHistorySetRefMark::SetInDoc( SwDoc* pDoc, bool )
346 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
347 ASSERT( pTxtNd, "SwHistorySetRefMark: no TextNode" );
348 if ( !pTxtNd )
349 return;
351 SwFmtRefMark aRefMark( m_RefName );
353 // if a reference mark without an end already exists here: must not insert!
354 if ( m_nStart != m_nEnd ||
355 !pTxtNd->GetTxtAttr( m_nStart, RES_TXTATR_REFMARK ) )
357 pTxtNd->InsertItem( aRefMark, m_nStart, m_nEnd,
358 nsSetAttrMode::SETATTR_NOTXTATRCHR );
363 SwHistorySetTOXMark::SwHistorySetTOXMark( SwTxtTOXMark* pTxtHt, ULONG nNodePos )
364 : SwHistoryHint( HSTRY_SETTOXMARKHNT )
365 , m_TOXMark( pTxtHt->GetTOXMark() )
366 , m_TOXName( m_TOXMark.GetTOXType()->GetTypeName() )
367 , m_eTOXTypes( m_TOXMark.GetTOXType()->GetType() )
368 , m_nNodeIndex( nNodePos )
369 , m_nStart( *pTxtHt->GetStart() )
370 , m_nEnd( *pTxtHt->GetAnyEnd() )
372 const_cast<SwModify*>(m_TOXMark.GetRegisteredIn())->Remove( &m_TOXMark );
376 void SwHistorySetTOXMark::SetInDoc( SwDoc* pDoc, bool )
378 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
379 ASSERT( pTxtNd, "SwHistorySetTOXMark: no TextNode" );
380 if ( !pTxtNd )
381 return;
383 // search for respective TOX type
384 USHORT nCnt = pDoc->GetTOXTypeCount( m_eTOXTypes );
385 SwTOXType* pToxType = 0;
386 for ( USHORT n = 0; n < nCnt; ++n )
388 pToxType = const_cast<SwTOXType*>(pDoc->GetTOXType( m_eTOXTypes, n ));
389 if ( pToxType->GetTypeName() == m_TOXName )
390 break;
391 pToxType = 0;
394 if ( !pToxType ) // TOX type not found, create new
396 pToxType = const_cast<SwTOXType*>(
397 pDoc->InsertTOXType( SwTOXType( m_eTOXTypes, m_TOXName )));
400 SwTOXMark aNew( m_TOXMark );
401 pToxType->Add( &aNew );
403 pTxtNd->InsertItem( aNew, m_nStart, m_nEnd,
404 nsSetAttrMode::SETATTR_NOTXTATRCHR );
408 int SwHistorySetTOXMark::IsEqual( const SwTOXMark& rCmp ) const
410 return m_TOXName == rCmp.GetTOXType()->GetTypeName() &&
411 m_eTOXTypes == rCmp.GetTOXType()->GetType() &&
412 m_TOXMark.GetAlternativeText() == rCmp.GetAlternativeText() &&
413 ( (TOX_INDEX == m_eTOXTypes)
414 ? ( m_TOXMark.GetPrimaryKey() == rCmp.GetPrimaryKey() &&
415 m_TOXMark.GetSecondaryKey() == rCmp.GetSecondaryKey() )
416 : m_TOXMark.GetLevel() == rCmp.GetLevel()
421 SwHistoryResetTxt::SwHistoryResetTxt( USHORT nWhich,
422 xub_StrLen nAttrStart, xub_StrLen nAttrEnd, ULONG nNodePos )
423 : SwHistoryHint( HSTRY_RESETTXTHNT )
424 , m_nNodeIndex( nNodePos ), m_nStart( nAttrStart ), m_nEnd( nAttrEnd )
425 , m_nAttr( nWhich )
430 void SwHistoryResetTxt::SetInDoc( SwDoc* pDoc, bool )
432 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
433 ASSERT( pTxtNd, "SwHistoryResetTxt: no TextNode" );
434 if ( pTxtNd )
436 pTxtNd->Delete( m_nAttr, m_nStart, m_nEnd );
441 SwHistorySetFootnote::SwHistorySetFootnote( SwTxtFtn* pTxtFtn, ULONG nNodePos )
442 : SwHistoryHint( HSTRY_SETFTNHNT )
443 , m_pUndo( new SwUndoSaveSection )
444 , m_FootnoteNumber( pTxtFtn->GetFtn().GetNumStr() )
445 , m_nNodeIndex( nNodePos )
446 , m_nStart( *pTxtFtn->GetStart() )
447 , m_bEndNote( pTxtFtn->GetFtn().IsEndNote() )
449 ASSERT( pTxtFtn->GetStartNode(),
450 "SwHistorySetFootnote: Footnote without Section" );
452 // merke die alte NodePos, denn wer weiss was alles in der SaveSection
453 // gespeichert (geloescht) wird
454 SwDoc* pDoc = const_cast<SwDoc*>(pTxtFtn->GetTxtNode().GetDoc());
455 SwNode* pSaveNd = pDoc->GetNodes()[ m_nNodeIndex ];
457 //Pointer auf StartNode der FtnSection merken und erstmal den Pointer im
458 //Attribut zuruecksetzen -> Damit werden automatisch die Frms vernichtet.
459 SwNodeIndex aSttIdx( *pTxtFtn->GetStartNode() );
460 pTxtFtn->SetStartNode( 0, FALSE );
462 m_pUndo->SaveSection( pDoc, aSttIdx );
463 m_nNodeIndex = pSaveNd->GetIndex();
466 SwHistorySetFootnote::SwHistorySetFootnote( const SwTxtFtn &rTxtFtn )
467 : SwHistoryHint( HSTRY_SETFTNHNT )
468 , m_pUndo( 0 )
469 , m_FootnoteNumber( rTxtFtn.GetFtn().GetNumStr() )
470 , m_nNodeIndex( _SwTxtFtn_GetIndex( (&rTxtFtn) ) )
471 , m_nStart( *rTxtFtn.GetStart() )
472 , m_bEndNote( rTxtFtn.GetFtn().IsEndNote() )
474 ASSERT( rTxtFtn.GetStartNode(),
475 "SwHistorySetFootnote: Footnote without Section" );
478 String SwHistorySetFootnote::GetDescription() const
480 return SW_RES(STR_FOOTNOTE);
483 SwHistorySetFootnote::~SwHistorySetFootnote()
488 void SwHistorySetFootnote::SetInDoc( SwDoc* pDoc, bool )
490 SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
491 ASSERT( pTxtNd, "SwHistorySetFootnote: no TextNode" );
492 if ( !pTxtNd )
493 return;
495 if ( m_pUndo.get() )
497 // set the footnote in the TextNode
498 SwFmtFtn aTemp( m_bEndNote );
499 SwFmtFtn& rNew = const_cast<SwFmtFtn&>(
500 static_cast<const SwFmtFtn&>(pDoc->GetAttrPool().Put(aTemp)) );
501 if ( m_FootnoteNumber.Len() )
503 rNew.SetNumStr( m_FootnoteNumber );
505 SwTxtFtn* pTxtFtn = new SwTxtFtn( rNew, m_nStart );
507 // create the section of the Footnote
508 SwNodeIndex aIdx( *pTxtNd );
509 m_pUndo->RestoreSection( pDoc, &aIdx, SwFootnoteStartNode );
510 pTxtFtn->SetStartNode( &aIdx );
511 if ( m_pUndo->GetHistory() )
513 // create frames only now
514 m_pUndo->GetHistory()->Rollback( pDoc );
517 pTxtNd->Insert( pTxtFtn );
519 else
521 SwTxtFtn *pFtn = const_cast<SwTxtFtn*>(
522 static_cast<const SwTxtFtn*>(pTxtNd->GetTxtAttr( m_nStart )));
523 SwFmtFtn &rFtn = const_cast<SwFmtFtn&>(pFtn->GetFtn());
524 rFtn.SetNumStr( m_FootnoteNumber );
525 if ( rFtn.IsEndNote() != m_bEndNote )
527 rFtn.SetEndNote( m_bEndNote );
528 pFtn->CheckCondColl();
534 SwHistoryChangeFmtColl::SwHistoryChangeFmtColl( SwFmtColl* pFmtColl, ULONG nNd,
535 BYTE nNodeWhich )
536 : SwHistoryHint( HSTRY_CHGFMTCOLL )
537 , m_pColl( pFmtColl )
538 , m_nNodeIndex( nNd )
539 , m_nNodeType( nNodeWhich )
543 void SwHistoryChangeFmtColl::SetInDoc( SwDoc* pDoc, bool )
545 SwCntntNode * pCntntNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetCntntNode();
546 ASSERT( pCntntNd, "SwHistoryChangeFmtColl: no ContentNode" );
548 // before setting the format, check if it is still available in the
549 // document. if it has been deleted, there is no undo!
550 if ( pCntntNd && m_nNodeType == pCntntNd->GetNodeType() )
552 if ( ND_TEXTNODE == m_nNodeType )
554 if ( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos(
555 static_cast<SwTxtFmtColl * const>(m_pColl) ))
557 pCntntNd->ChgFmtColl( m_pColl );
560 else if ( USHRT_MAX != pDoc->GetGrfFmtColls()->GetPos(
561 static_cast<SwGrfFmtColl * const>(m_pColl) ))
563 pCntntNd->ChgFmtColl( m_pColl );
569 SwHistoryTxtFlyCnt::SwHistoryTxtFlyCnt( SwFrmFmt* const pFlyFmt )
570 : SwHistoryHint( HSTRY_FLYCNT )
571 , m_pUndo( new SwUndoDelLayFmt( pFlyFmt ) )
573 ASSERT( pFlyFmt, "SwHistoryTxtFlyCnt: no Format" );
574 m_pUndo->ChgShowSel( FALSE );
578 SwHistoryTxtFlyCnt::~SwHistoryTxtFlyCnt()
583 void SwHistoryTxtFlyCnt::SetInDoc( SwDoc* pDoc, bool )
585 SwPaM aPam( pDoc->GetNodes().GetEndOfPostIts() );
586 SwUndoIter aUndoIter( &aPam );
587 m_pUndo->Undo( aUndoIter );
592 SwHistoryBookmark::SwHistoryBookmark(
593 const ::sw::mark::IMark& rBkmk,
594 bool bSavePos,
595 bool bSaveOtherPos)
596 : SwHistoryHint(HSTRY_BOOKMARK)
597 , m_aName(rBkmk.GetName())
598 , m_aShortName()
599 , m_aKeycode()
600 , m_nNode(bSavePos ?
601 rBkmk.GetMarkPos().nNode.GetIndex() : 0)
602 , m_nOtherNode(bSaveOtherPos ?
603 rBkmk.GetOtherMarkPos().nNode.GetIndex() : 0)
604 , m_nCntnt(bSavePos ?
605 rBkmk.GetMarkPos().nContent.GetIndex() : 0)
606 , m_nOtherCntnt(bSaveOtherPos ?
607 rBkmk.GetOtherMarkPos().nContent.GetIndex() :0)
608 , m_bSavePos(bSavePos)
609 , m_bSaveOtherPos(bSaveOtherPos)
610 , m_bHadOtherPos(rBkmk.IsExpanded())
611 , m_eBkmkType(IDocumentMarkAccess::GetType(rBkmk))
613 const ::sw::mark::IBookmark* const pBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(&rBkmk);
614 if(pBookmark)
616 m_aKeycode = pBookmark->GetKeyCode();
617 m_aShortName = pBookmark->GetShortName();
622 void SwHistoryBookmark::SetInDoc( SwDoc* pDoc, bool )
624 bool bDoesUndo = pDoc->DoesUndo();
625 pDoc->DoUndo(false);
627 SwNodes& rNds = pDoc->GetNodes();
628 IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
629 ::std::auto_ptr<SwPaM> pPam;
630 ::sw::mark::IMark* pMark = NULL;
632 if(m_bSavePos)
634 SwCntntNode* const pCntntNd = rNds[m_nNode]->GetCntntNode();
635 OSL_ENSURE(pCntntNd,
636 "<SwHistoryBookmark::SetInDoc(..)>"
637 " - wrong node for a mark");
639 // #111660# don't crash when nNode1 doesn't point to content node.
640 if(pCntntNd)
641 pPam = ::std::auto_ptr<SwPaM>(new SwPaM(*pCntntNd, m_nCntnt));
643 else
645 pMark = pMarkAccess->findMark(m_aName)->get();
646 pPam = ::std::auto_ptr<SwPaM>(new SwPaM(pMark->GetMarkPos()));
649 if(m_bSaveOtherPos)
651 SwCntntNode* const pCntntNd = rNds[m_nOtherNode]->GetCntntNode();
652 OSL_ENSURE(pCntntNd,
653 "<SwHistoryBookmark::SetInDoc(..)>"
654 " - wrong node for a mark");
656 if(pPam.get() != NULL && pCntntNd)
658 pPam->SetMark();
659 pPam->GetMark()->nNode = m_nOtherNode;
660 pPam->GetMark()->nContent.Assign(pCntntNd, m_nOtherCntnt);
663 else if(m_bHadOtherPos)
665 if(!pMark)
666 pMark = pMarkAccess->findMark(m_aName)->get();
667 OSL_ENSURE(pMark->IsExpanded(),
668 "<SwHistoryBookmark::SetInDoc(..)>"
669 " - missing pos on old mark");
670 pPam->SetMark();
671 *pPam->GetMark() = pMark->GetOtherMarkPos();
674 if(pPam.get())
676 if(pMark)
677 pMarkAccess->deleteMark(pMark);
678 ::sw::mark::IBookmark* const pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(
679 pMarkAccess->makeMark(*pPam, m_aName, m_eBkmkType));
680 if(pBookmark)
682 pBookmark->SetKeyCode(m_aKeycode);
683 pBookmark->SetShortName(m_aShortName);
686 pDoc->DoUndo(bDoesUndo);
690 bool SwHistoryBookmark::IsEqualBookmark(const ::sw::mark::IMark& rBkmk)
692 return m_nNode == rBkmk.GetMarkPos().nNode.GetIndex()
693 && m_nCntnt == rBkmk.GetMarkPos().nContent.GetIndex()
694 && m_aName == rBkmk.GetName();
697 const ::rtl::OUString& SwHistoryBookmark::GetName() const
699 return m_aName;
702 /*************************************************************************/
705 SwHistorySetAttrSet::SwHistorySetAttrSet( const SfxItemSet& rSet,
706 ULONG nNodePos, const SvUShortsSort& rSetArr )
707 : SwHistoryHint( HSTRY_SETATTRSET )
708 , m_OldSet( rSet )
709 , m_ResetArray( 0, 4 )
710 , m_nNodeIndex( nNodePos )
712 SfxItemIter aIter( m_OldSet ), aOrigIter( rSet );
713 const SfxPoolItem* pItem = aIter.FirstItem(),
714 * pOrigItem = aOrigIter.FirstItem();
715 do {
716 if( !rSetArr.Seek_Entry( pOrigItem->Which() ))
718 m_ResetArray.Insert( pOrigItem->Which(), m_ResetArray.Count() );
719 m_OldSet.ClearItem( pOrigItem->Which() );
721 else
723 switch ( pItem->Which() )
725 case RES_PAGEDESC:
726 static_cast<SwFmtPageDesc*>(
727 const_cast<SfxPoolItem*>(pItem))->ChgDefinedIn( 0 );
728 break;
730 case RES_PARATR_DROP:
731 static_cast<SwFmtDrop*>(
732 const_cast<SfxPoolItem*>(pItem))->ChgDefinedIn( 0 );
733 break;
735 case RES_BOXATR_FORMULA:
737 //JP 20.04.98: Bug 49502 - wenn eine Formel gesetzt ist, nie den
738 // Value mit sichern. Der muss gegebenfalls neu
739 // errechnet werden!
740 //JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
741 m_OldSet.ClearItem( RES_BOXATR_VALUE );
743 SwTblBoxFormula& rNew =
744 *static_cast<SwTblBoxFormula*>(
745 const_cast<SfxPoolItem*>(pItem));
746 if ( rNew.IsIntrnlName() )
748 const SwTblBoxFormula& rOld =
749 static_cast<const SwTblBoxFormula&>(
750 rSet.Get( RES_BOXATR_FORMULA ));
751 const SwNode* pNd = rOld.GetNodeOfFormula();
752 if ( pNd )
754 const SwTableNode* pTableNode
755 = pNd->FindTableNode();
756 if (pTableNode)
758 SwTableFmlUpdate aMsgHnt(
759 &pTableNode->GetTable() );
760 aMsgHnt.eFlags = TBL_BOXNAME;
761 rNew.ChgDefinedIn( rOld.GetDefinedIn() );
762 rNew.ChangeState( &aMsgHnt );
766 rNew.ChgDefinedIn( 0 );
768 break;
772 if( aIter.IsAtEnd() )
773 break;
774 pItem = aIter.NextItem();
775 pOrigItem = aOrigIter.NextItem();
776 } while( TRUE );
779 void SwHistorySetAttrSet::SetInDoc( SwDoc* pDoc, bool )
781 BOOL bDoesUndo = pDoc->DoesUndo();
782 pDoc->DoUndo( FALSE );
784 SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
785 if ( pNode->IsCntntNode() )
787 static_cast<SwCntntNode*>(pNode)->SetAttr( m_OldSet );
788 if ( m_ResetArray.Count() )
790 static_cast<SwCntntNode*>(pNode)->ResetAttr( m_ResetArray );
793 else if ( pNode->IsTableNode() )
795 SwFmt& rFmt =
796 *static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt();
797 rFmt.SetFmtAttr( m_OldSet );
798 if ( m_ResetArray.Count() )
800 rFmt.ResetFmtAttr( *m_ResetArray.GetData() );
804 pDoc->DoUndo( bDoesUndo );
807 /*************************************************************************/
810 SwHistoryResetAttrSet::SwHistoryResetAttrSet( const SfxItemSet& rSet,
811 ULONG nNodePos, xub_StrLen nAttrStt, xub_StrLen nAttrEnd )
812 : SwHistoryHint( HSTRY_RESETATTRSET )
813 , m_nNodeIndex( nNodePos ), m_nStart( nAttrStt ), m_nEnd( nAttrEnd )
814 , m_Array( (BYTE)rSet.Count() )
816 SfxItemIter aIter( rSet );
817 bool bAutoStyle = true;
819 while( TRUE )
821 const USHORT nWhich = aIter.GetCurItem()->Which();
822 // Character attribute cannot be inserted into the hints array
823 // anymore. Therefore we have to treat them as one RES_TXTATR_AUTOFMT:
824 if (isCHRATR(nWhich))
826 bAutoStyle = true;
828 else
830 m_Array.Insert( aIter.GetCurItem()->Which(), m_Array.Count() );
833 if( aIter.IsAtEnd() )
834 break;
836 aIter.NextItem();
839 if ( bAutoStyle )
841 m_Array.Insert( RES_TXTATR_AUTOFMT, m_Array.Count() );
846 void SwHistoryResetAttrSet::SetInDoc( SwDoc* pDoc, bool )
848 BOOL bDoesUndo = pDoc->DoesUndo();
849 pDoc->DoUndo( FALSE );
851 SwCntntNode * pCntntNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetCntntNode();
852 ASSERT( pCntntNd, "SwHistoryResetAttrSet: no CntntNode" );
854 if (pCntntNd)
856 const USHORT* pArr = m_Array.GetData();
857 if ( USHRT_MAX == m_nEnd && USHRT_MAX == m_nStart )
859 // no area: use ContentNode
860 for ( USHORT n = m_Array.Count(); n; --n, ++pArr )
862 pCntntNd->ResetAttr( *pArr );
865 else
867 // area: use TextNode
868 for ( USHORT n = m_Array.Count(); n; --n, ++pArr )
870 static_cast<SwTxtNode*>(pCntntNd)->
871 Delete( *pArr, m_nStart, m_nEnd );
876 pDoc->DoUndo( bDoesUndo );
880 /*************************************************************************/
883 SwHistoryChangeFlyAnchor::SwHistoryChangeFlyAnchor( SwFrmFmt& rFmt )
884 : SwHistoryHint( HSTRY_CHGFLYANCHOR )
885 , m_rFmt( rFmt )
886 , m_nOldNodeIndex( rFmt.GetAnchor().GetCntntAnchor()->nNode.GetIndex() )
887 , m_nOldContentIndex( ( FLY_AUTO_CNTNT == rFmt.GetAnchor().GetAnchorId() )
888 ? rFmt.GetAnchor().GetCntntAnchor()->nContent.GetIndex()
889 : STRING_MAXLEN )
894 void SwHistoryChangeFlyAnchor::SetInDoc( SwDoc* pDoc, bool )
896 BOOL bDoesUndo = pDoc->DoesUndo();
897 pDoc->DoUndo( FALSE );
899 USHORT nPos = pDoc->GetSpzFrmFmts()->GetPos( &m_rFmt );
900 if ( USHRT_MAX != nPos ) // Format does still exist
902 SwFmtAnchor aTmp( m_rFmt.GetAnchor() );
904 SwNode* pNd = pDoc->GetNodes()[ m_nOldNodeIndex ];
905 SwCntntNode* pCNd = pNd->GetCntntNode();
906 SwPosition aPos( *pNd );
907 if ( STRING_MAXLEN != m_nOldContentIndex )
909 ASSERT(pCNd, "SwHistoryChangeFlyAnchor: no ContentNode");
910 if (pCNd)
912 aPos.nContent.Assign( pCNd, m_nOldContentIndex );
915 aTmp.SetAnchor( &aPos );
917 // so the Layout does not get confused
918 if ( !pCNd || !pCNd->GetFrm( 0, 0, FALSE ) )
920 m_rFmt.DelFrms();
923 m_rFmt.SetFmtAttr( aTmp );
925 pDoc->DoUndo( bDoesUndo );
929 /*************************************************************************/
931 SwHistoryChangeFlyChain::SwHistoryChangeFlyChain( SwFlyFrmFmt& rFmt,
932 const SwFmtChain& rAttr )
933 : SwHistoryHint( HSTRY_CHGFLYCHAIN )
934 , m_pPrevFmt( rAttr.GetPrev() )
935 , m_pNextFmt( rAttr.GetNext() )
936 , m_pFlyFmt( &rFmt )
941 void SwHistoryChangeFlyChain::SetInDoc( SwDoc* pDoc, bool )
943 if ( USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pFlyFmt ) )
945 SwFmtChain aChain;
947 if ( m_pPrevFmt &&
948 USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pPrevFmt ) )
950 aChain.SetPrev( m_pPrevFmt );
951 SwFmtChain aTmp( m_pPrevFmt->GetChain() );
952 aTmp.SetNext( m_pFlyFmt );
953 m_pPrevFmt->SetFmtAttr( aTmp );
956 if ( m_pNextFmt &&
957 USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pNextFmt ) )
959 aChain.SetNext( m_pNextFmt );
960 SwFmtChain aTmp( m_pNextFmt->GetChain() );
961 aTmp.SetPrev( m_pFlyFmt );
962 m_pNextFmt->SetFmtAttr( aTmp );
965 if ( aChain.GetNext() || aChain.GetPrev() )
967 m_pFlyFmt->SetFmtAttr( aChain );
973 // -> #i27615#
974 SwHistoryChangeCharFmt::SwHistoryChangeCharFmt(const SfxItemSet & rSet,
975 const String & sFmt)
976 : SwHistoryHint(HSTRY_CHGCHARFMT)
977 , m_OldSet(rSet), m_Fmt(sFmt)
981 void SwHistoryChangeCharFmt::SetInDoc(SwDoc * pDoc, bool )
983 SwCharFmt * pCharFmt = pDoc->FindCharFmtByName(m_Fmt);
985 if (pCharFmt)
987 pCharFmt->SetFmtAttr(m_OldSet);
990 // <- #i27615#
992 /* \f */
995 SwHistory::SwHistory( USHORT nInitSz, USHORT nGrowSz )
996 : m_SwpHstry( (BYTE)nInitSz, (BYTE)nGrowSz )
997 , m_nEndDiff( 0 )
1001 SwHistory::~SwHistory()
1003 Delete( 0 );
1007 /*************************************************************************
1009 |* void SwHistory::Add()
1011 |* Beschreibung Dokument 1.0
1012 |* Ersterstellung JP 18.02.91
1013 |* Letzte Aenderung JP 18.02.91
1015 *************************************************************************/
1017 // --> OD 2008-02-27 #refactorlists# - removed <rDoc>
1018 void SwHistory::Add( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue,
1019 ULONG nNodeIdx )
1020 // <--
1022 ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
1024 USHORT nWhich = pNewValue->Which();
1025 if( (nWhich >= POOLATTR_END) || (nWhich == RES_TXTATR_FIELD) )
1026 return;
1028 // no default Attribute?
1029 SwHistoryHint * pHt;
1030 if ( pOldValue && pOldValue != GetDfltAttr( pOldValue->Which() ) )
1032 pHt = new SwHistorySetFmt( pOldValue, nNodeIdx );
1034 else
1036 pHt = new SwHistoryResetFmt( pNewValue, nNodeIdx );
1038 m_SwpHstry.Insert( pHt, Count() );
1042 void SwHistory::Add( SwTxtAttr* pHint, ULONG nNodeIdx, bool bNewAttr )
1044 ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
1046 SwHistoryHint * pHt;
1047 USHORT nAttrWhich = pHint->Which();
1049 if( !bNewAttr )
1051 switch ( nAttrWhich )
1053 case RES_TXTATR_FTN:
1054 pHt = new SwHistorySetFootnote(
1055 static_cast<SwTxtFtn*>(pHint), nNodeIdx );
1056 break;
1057 case RES_TXTATR_FLYCNT:
1058 pHt = new SwHistoryTxtFlyCnt( static_cast<SwTxtFlyCnt*>(pHint)
1059 ->GetFlyCnt().GetFrmFmt() );
1060 break;
1061 case RES_TXTATR_FIELD:
1062 pHt = new SwHistorySetTxtFld(
1063 static_cast<SwTxtFld*>(pHint), nNodeIdx );
1064 break;
1065 case RES_TXTATR_TOXMARK:
1066 pHt = new SwHistorySetTOXMark(
1067 static_cast<SwTxtTOXMark*>(pHint), nNodeIdx );
1068 break;
1069 case RES_TXTATR_REFMARK:
1070 pHt = new SwHistorySetRefMark(
1071 static_cast<SwTxtRefMark*>(pHint), nNodeIdx );
1072 break;
1073 default:
1074 pHt = new SwHistorySetTxt(
1075 static_cast<SwTxtAttr*>(pHint), nNodeIdx );
1078 else
1080 pHt = new SwHistoryResetTxt( pHint->Which(), *pHint->GetStart(),
1081 *pHint->GetAnyEnd(), nNodeIdx );
1083 m_SwpHstry.Insert( pHt, Count() );
1087 void SwHistory::Add( SwFmtColl* pColl, ULONG nNodeIdx, BYTE nWhichNd )
1089 ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
1091 SwHistoryHint * pHt =
1092 new SwHistoryChangeFmtColl( pColl, nNodeIdx, nWhichNd );
1093 m_SwpHstry.Insert( pHt, Count() );
1097 void SwHistory::Add(const ::sw::mark::IMark& rBkmk, bool bSavePos, bool bSaveOtherPos)
1099 ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
1101 SwHistoryHint * pHt = new SwHistoryBookmark(rBkmk, bSavePos, bSaveOtherPos);
1102 m_SwpHstry.Insert( pHt, Count() );
1106 void SwHistory::Add( SwFrmFmt& rFmt )
1108 SwHistoryHint * pHt = new SwHistoryChangeFlyAnchor( rFmt );
1109 m_SwpHstry.Insert( pHt, Count() );
1112 void SwHistory::Add( SwFlyFrmFmt& rFmt, USHORT& rSetPos )
1114 ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
1116 SwHistoryHint * pHint;
1117 const USHORT nWh = rFmt.Which();
1118 if( RES_FLYFRMFMT == nWh || RES_DRAWFRMFMT == nWh )
1120 pHint = new SwHistoryTxtFlyCnt( &rFmt );
1121 m_SwpHstry.Insert( pHint, Count() );
1123 const SwFmtChain* pChainItem;
1124 if( SFX_ITEM_SET == rFmt.GetItemState( RES_CHAIN, FALSE,
1125 (const SfxPoolItem**)&pChainItem ))
1127 if( pChainItem->GetNext() || pChainItem->GetPrev() )
1129 SwHistoryHint * pHt =
1130 new SwHistoryChangeFlyChain( rFmt, *pChainItem );
1131 m_SwpHstry.Insert( pHt, rSetPos++ );
1132 if ( pChainItem->GetNext() )
1134 SwFmtChain aTmp( pChainItem->GetNext()->GetChain() );
1135 aTmp.SetPrev( 0 );
1136 pChainItem->GetNext()->SetFmtAttr( aTmp );
1138 if ( pChainItem->GetPrev() )
1140 SwFmtChain aTmp( pChainItem->GetPrev()->GetChain() );
1141 aTmp.SetNext( 0 );
1142 pChainItem->GetPrev()->SetFmtAttr( aTmp );
1145 rFmt.ResetFmtAttr( RES_CHAIN );
1150 void SwHistory::Add( const SwTxtFtn& rFtn )
1152 SwHistoryHint *pHt = new SwHistorySetFootnote( rFtn );
1153 m_SwpHstry.Insert( pHt, Count() );
1156 // #i27615#
1157 void SwHistory::Add(const SfxItemSet & rSet, const SwCharFmt & rFmt)
1159 SwHistoryHint * pHt = new SwHistoryChangeCharFmt(rSet, rFmt.GetName());
1160 m_SwpHstry.Insert(pHt, Count());
1163 /*************************************************************************
1165 |* BOOL SwHistory::Rollback()
1167 |* Beschreibung Dokument 1.0
1168 |* Ersterstellung JP 18.02.91
1169 |* Letzte Aenderung JP 18.02.91
1171 *************************************************************************/
1174 bool SwHistory::Rollback( SwDoc* pDoc, USHORT nStart )
1176 if ( !Count() )
1177 return false;
1179 SwHistoryHint * pHHt;
1180 USHORT i;
1181 for ( i = Count(); i > nStart ; )
1183 pHHt = m_SwpHstry[ --i ];
1184 pHHt->SetInDoc( pDoc, false );
1185 delete pHHt;
1187 m_SwpHstry.Remove( nStart, Count() - nStart );
1188 m_nEndDiff = 0;
1189 return true;
1194 bool SwHistory::TmpRollback( SwDoc* pDoc, USHORT nStart, bool bToFirst )
1196 USHORT nEnd = Count() - m_nEndDiff;
1197 if ( !Count() || !nEnd || nStart >= nEnd )
1198 return false;
1200 SwHistoryHint * pHHt;
1201 if ( bToFirst )
1203 for ( ; nEnd > nStart; ++m_nEndDiff )
1205 pHHt = m_SwpHstry[ --nEnd ];
1206 pHHt->SetInDoc( pDoc, true );
1209 else
1211 for ( ; nStart < nEnd; ++m_nEndDiff, ++nStart )
1213 pHHt = m_SwpHstry[ nStart ];
1214 pHHt->SetInDoc( pDoc, true );
1217 return true;
1221 void SwHistory::Delete( USHORT nStart )
1223 for ( USHORT n = Count(); n > nStart; )
1225 m_SwpHstry.DeleteAndDestroy( --n, 1 );
1227 m_nEndDiff = 0;
1231 USHORT SwHistory::SetTmpEnd( USHORT nNewTmpEnd )
1233 ASSERT( nNewTmpEnd <= Count(), "SwHistory::SetTmpEnd: out of bounds" );
1235 USHORT nOld = Count() - m_nEndDiff;
1236 m_nEndDiff = Count() - nNewTmpEnd;
1238 // for every SwHistoryFlyCnt, call the Redo of its UndoObject.
1239 // this saves the formats of the flys!
1240 for ( USHORT n = nOld; n < nNewTmpEnd; n++ )
1242 if ( HSTRY_FLYCNT == (*this)[ n ]->Which() )
1244 static_cast<SwHistoryTxtFlyCnt*>((*this)[ n ])
1245 ->GetUDelLFmt()->Redo();
1249 return nOld;
1252 void SwHistory::CopyFmtAttr( const SfxItemSet& rSet, ULONG nNodeIdx )
1254 if( rSet.Count() )
1256 SfxItemIter aIter( rSet );
1257 do {
1258 if( (SfxPoolItem*)-1 != aIter.GetCurItem() )
1260 const SfxPoolItem* pNew = aIter.GetCurItem();
1261 Add( pNew, pNew, nNodeIdx );
1263 if( aIter.IsAtEnd() )
1264 break;
1265 aIter.NextItem();
1266 } while( TRUE );
1270 void SwHistory::CopyAttr( SwpHints* pHts, ULONG nNodeIdx,
1271 xub_StrLen nStart, xub_StrLen nEnd, bool bFields )
1273 if( !pHts )
1274 return;
1276 // copy all attributes of the TextNode in the area from nStart to nEnd
1277 SwTxtAttr* pHt;
1278 xub_StrLen nAttrStt;
1279 const xub_StrLen * pEndIdx;
1280 for( USHORT n = 0; n < pHts->Count(); n++ )
1282 // BP: nAttrStt muss auch bei !pEndIdx gesetzt werden
1283 pHt = pHts->GetTextHint(n);
1284 nAttrStt = *pHt->GetStart();
1285 // JP: ???? wieso nAttrStt >= nEnd
1286 // if( 0 != ( pEndIdx = pHt->GetEnd() ) && nAttrStt >= nEnd )
1287 if( 0 != ( pEndIdx = pHt->GetEnd() ) && nAttrStt > nEnd )
1288 break;
1290 // Flys und Ftn nie kopieren !!
1291 BOOL bNextAttr = FALSE;
1292 switch( pHt->Which() )
1294 case RES_TXTATR_FIELD:
1295 case RES_TXTATR_HARDBLANK:
1296 // keine Felder, .. kopieren ??
1297 if( !bFields )
1298 bNextAttr = TRUE;
1299 break;
1300 case RES_TXTATR_FLYCNT:
1301 case RES_TXTATR_FTN:
1302 bNextAttr = TRUE;
1303 break;
1306 if( bNextAttr )
1307 continue;
1309 // save all attributes that are somehow in this area
1310 if ( nStart <= nAttrStt )
1312 if ( nEnd > nAttrStt
1313 // JP: ???? wieso nAttrStt >= nEnd
1314 // || (nEnd == nAttrStt && (!pEndIdx || nEnd == pEndIdx->GetIndex()))
1317 Add( pHt, nNodeIdx, false );
1320 else if ( pEndIdx && nStart < *pEndIdx )
1322 Add( pHt, nNodeIdx, false );
1328 /*************************************************************************/
1330 // Klasse zum Registrieren der History am Node, Format, HintsArray, ...
1332 SwRegHistory::SwRegHistory( SwHistory* pHst )
1333 : SwClient( 0 )
1334 , m_pHistory( pHst )
1335 , m_nNodeIndex( ULONG_MAX )
1337 _MakeSetWhichIds();
1340 SwRegHistory::SwRegHistory( SwModify* pRegIn, const SwNode& rNd,
1341 SwHistory* pHst )
1342 : SwClient( pRegIn )
1343 , m_pHistory( pHst )
1344 , m_nNodeIndex( rNd.GetIndex() )
1346 _MakeSetWhichIds();
1349 SwRegHistory::SwRegHistory( const SwNode& rNd, SwHistory* pHst )
1350 : SwClient( 0 )
1351 , m_pHistory( pHst )
1352 , m_nNodeIndex( rNd.GetIndex() )
1354 _MakeSetWhichIds();
1357 void SwRegHistory::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
1359 if ( m_pHistory && ( pOld || pNew ) )
1361 if ( pNew->Which() < POOLATTR_END )
1363 m_pHistory->Add( pOld, pNew, m_nNodeIndex );
1365 else if ( RES_ATTRSET_CHG == pNew->Which() )
1367 SwHistoryHint* pNewHstr;
1368 const SfxItemSet& rSet =
1369 *static_cast<SwAttrSetChg*>(pOld)->GetChgSet();
1370 if ( 1 < rSet.Count() )
1372 pNewHstr =
1373 new SwHistorySetAttrSet( rSet, m_nNodeIndex, m_WhichIdSet );
1375 else
1377 const SfxPoolItem* pItem = SfxItemIter( rSet ).FirstItem();
1378 if ( m_WhichIdSet.Seek_Entry( pItem->Which() ) )
1380 pNewHstr = new SwHistorySetFmt( pItem, m_nNodeIndex );
1382 else
1384 pNewHstr = new SwHistoryResetFmt( pItem, m_nNodeIndex );
1387 m_pHistory->m_SwpHstry.Insert( pNewHstr, m_pHistory->Count() );
1394 void SwRegHistory::AddHint( SwTxtAttr* pHt, const bool bNew )
1396 m_pHistory->Add( pHt, m_nNodeIndex, bNew );
1400 SwRegHistory::SwRegHistory( SwTxtNode* pTxtNode, const SfxItemSet& rSet,
1401 xub_StrLen nStart, xub_StrLen nEnd, USHORT nFlags,
1402 SwHistory* pHst )
1403 : SwClient( pTxtNode )
1404 , m_pHistory( pHst )
1405 , m_nNodeIndex( pTxtNode->GetIndex() )
1407 if( !rSet.Count() )
1408 return;
1410 BOOL bInsert;
1412 if( pTxtNode->GetpSwpHints() && pHst )
1414 pTxtNode->GetpSwpHints()->Register( this );
1415 bInsert = pTxtNode->SetAttr( rSet, nStart, nEnd, nFlags );
1416 // Achtung: Durch das Einfuegen eines Attributs kann das Array
1417 // geloescht werden!!! Wenn das einzufuegende zunaechst ein vorhandenes
1418 // loescht, selbst aber nicht eingefuegt werden braucht, weil die
1419 // Absatzattribute identisch sind( -> bForgetAttr in SwpHints::Insert )
1420 if ( pTxtNode->GetpSwpHints() )
1421 pTxtNode->GetpSwpHints()->DeRegister();
1423 else
1424 bInsert = pTxtNode->SetAttr( rSet, nStart, nEnd, nFlags );
1426 if( pHst && bInsert )
1428 SwHistoryHint* pNewHstr = new SwHistoryResetAttrSet( rSet,
1429 pTxtNode->GetIndex(), nStart, nEnd );
1430 // der NodeIndex kann verschoben sein !!
1432 pHst->m_SwpHstry.Insert( pNewHstr, pHst->Count() );
1436 void SwRegHistory::RegisterInModify( SwModify* pRegIn, const SwNode& rNd )
1438 if ( m_pHistory && pRegIn )
1440 pRegIn->Add( this );
1441 m_nNodeIndex = rNd.GetIndex();
1442 _MakeSetWhichIds();
1444 else if ( m_WhichIdSet.Count() )
1446 m_WhichIdSet.Remove( 0, m_WhichIdSet.Count() );
1450 void SwRegHistory::_MakeSetWhichIds()
1452 if (!m_pHistory) return;
1454 if ( m_WhichIdSet.Count() )
1456 m_WhichIdSet.Remove( 0, m_WhichIdSet.Count() );
1459 if( GetRegisteredIn() )
1461 const SfxItemSet* pSet = 0;
1462 if( GetRegisteredIn()->ISA( SwCntntNode ) )
1464 pSet = static_cast<SwCntntNode*>(
1465 const_cast<SwModify*>(GetRegisteredIn()))->GetpSwAttrSet();
1467 else if ( GetRegisteredIn()->ISA( SwFmt ) )
1469 pSet = &static_cast<SwFmt*>(
1470 const_cast<SwModify*>(GetRegisteredIn()))->GetAttrSet();
1472 if( pSet && pSet->Count() )
1474 SfxItemIter aIter( *pSet );
1475 USHORT nW = aIter.FirstItem()->Which();
1476 while( TRUE )
1478 m_WhichIdSet.Insert( nW );
1479 if( aIter.IsAtEnd() )
1480 break;
1481 nW = aIter.NextItem()->Which();