summaryrefslogtreecommitdiff
path: root/sw/source/core/undo/rolbck.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/undo/rolbck.cxx')
-rw-r--r--sw/source/core/undo/rolbck.cxx1524
1 files changed, 1524 insertions, 0 deletions
diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx
new file mode 100644
index 000000000000..6df9f9aa24b8
--- /dev/null
+++ b/sw/source/core/undo/rolbck.cxx
@@ -0,0 +1,1524 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+#include <hintids.hxx>
+#include <svl/itemiter.hxx>
+#include <fmtftn.hxx>
+#include <fchrfmt.hxx>
+#include <fmtflcnt.hxx>
+#include <fmtrfmrk.hxx>
+#include <fmtfld.hxx>
+#include <fmtpdsc.hxx>
+#include <txtfld.hxx>
+#include <txtrfmrk.hxx>
+#include <txttxmrk.hxx>
+#include <txtftn.hxx>
+#include <txtflcnt.hxx>
+#include <fmtanchr.hxx>
+#include <fmtcnct.hxx>
+#include <frmfmt.hxx>
+#include <ftnidx.hxx>
+#include <doc.hxx> // SwDoc.GetNodes()
+#include <docary.hxx>
+#include <ndtxt.hxx> // SwTxtNode
+#include <paratr.hxx> //
+#include <cellatr.hxx> //
+#include <fldbas.hxx> // fuer Felder
+#include <pam.hxx> // fuer SwPaM
+#include <swtable.hxx>
+#include <rolbck.hxx>
+#include <ndgrf.hxx> // SwGrfNode
+#include <undobj.hxx> // fuer UndoDelete
+#include <IMark.hxx> // fuer SwBookmark
+#include <charfmt.hxx> // #i27615#
+#ifndef _COMCORE_HRC
+#include <comcore.hrc>
+#endif
+#include <tools/resid.hxx>
+#ifndef _UNDO_HRC
+#include <undo.hrc>
+#endif
+#include <editeng/brkitem.hxx>
+#include <bookmrk.hxx>
+
+SV_IMPL_PTRARR( SwpHstry, SwHistoryHintPtr)
+
+String SwHistoryHint::GetDescription() const
+{
+ return String();
+}
+
+
+SwHistorySetFmt::SwHistorySetFmt( const SfxPoolItem* pFmtHt, ULONG nNd )
+ : SwHistoryHint( HSTRY_SETFMTHNT )
+ , m_pAttr( pFmtHt->Clone() )
+ , m_nNodeIndex( nNd )
+{
+ switch ( m_pAttr->Which() )
+ {
+ case RES_PAGEDESC:
+ static_cast<SwFmtPageDesc&>(*m_pAttr).ChgDefinedIn( 0 );
+ break;
+ case RES_PARATR_DROP:
+ static_cast<SwFmtDrop&>(*m_pAttr).ChgDefinedIn( 0 );
+ break;
+ case RES_BOXATR_FORMULA:
+ {
+ //JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
+ SwTblBoxFormula& rNew = static_cast<SwTblBoxFormula&>(*m_pAttr);
+ if ( rNew.IsIntrnlName() )
+ {
+ const SwTblBoxFormula& rOld =
+ *static_cast<const SwTblBoxFormula*>(pFmtHt);
+ const SwNode* pNd = rOld.GetNodeOfFormula();
+ if ( pNd )
+ {
+ const SwTableNode* pTableNode = pNd->FindTableNode();
+ if (pTableNode)
+ {
+ SwTableFmlUpdate aMsgHnt( &pTableNode->GetTable() );
+ aMsgHnt.eFlags = TBL_BOXNAME;
+ rNew.ChgDefinedIn( rOld.GetDefinedIn() );
+ rNew.ChangeState( &aMsgHnt );
+ }
+ }
+ }
+ rNew.ChgDefinedIn( 0 );
+ }
+ break;
+ }
+}
+
+String SwHistorySetFmt::GetDescription() const
+{
+ String aResult ;
+
+ USHORT nWhich = m_pAttr->Which();
+ switch (nWhich)
+ {
+ case RES_BREAK:
+ switch ((static_cast<SvxFmtBreakItem &>(*m_pAttr)).GetBreak())
+ {
+ case SVX_BREAK_PAGE_BEFORE:
+ case SVX_BREAK_PAGE_AFTER:
+ case SVX_BREAK_PAGE_BOTH:
+ aResult = SW_RES(STR_UNDO_PAGEBREAKS);
+
+ break;
+ case SVX_BREAK_COLUMN_BEFORE:
+ case SVX_BREAK_COLUMN_AFTER:
+ case SVX_BREAK_COLUMN_BOTH:
+ aResult = SW_RES(STR_UNDO_COLBRKS);
+
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return aResult;
+}
+
+void SwHistorySetFmt::SetInDoc( SwDoc* pDoc, bool bTmpSet )
+{
+ SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
+ if ( pNode->IsCntntNode() )
+ {
+ static_cast<SwCntntNode*>(pNode)->SetAttr( *m_pAttr );
+ }
+ else if ( pNode->IsTableNode() )
+ {
+ static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt()->SetFmtAttr(
+ *m_pAttr );
+ }
+ else if ( pNode->IsStartNode() && (SwTableBoxStartNode ==
+ static_cast<SwStartNode*>(pNode)->GetStartNodeType()) )
+ {
+ SwTableNode* pTNd = pNode->FindTableNode();
+ if ( pTNd )
+ {
+ SwTableBox* pBox = pTNd->GetTable().GetTblBox( m_nNodeIndex );
+ if (pBox)
+ {
+ pBox->ClaimFrmFmt()->SetFmtAttr( *m_pAttr );
+ }
+ }
+ }
+
+ if ( !bTmpSet )
+ {
+ m_pAttr.reset();
+ }
+}
+
+SwHistorySetFmt::~SwHistorySetFmt()
+{
+}
+
+
+// --> OD 2008-02-27 #refactorlists# - removed <rDoc>
+SwHistoryResetFmt::SwHistoryResetFmt(const SfxPoolItem* pFmtHt, ULONG nNodeIdx)
+// <--
+ : SwHistoryHint( HSTRY_RESETFMTHNT )
+ , m_nNodeIndex( nNodeIdx )
+ , m_nWhich( pFmtHt->Which() )
+{
+}
+
+
+void SwHistoryResetFmt::SetInDoc( SwDoc* pDoc, bool )
+{
+ SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
+ if ( pNode->IsCntntNode() )
+ {
+ static_cast<SwCntntNode*>(pNode)->ResetAttr( m_nWhich );
+ }
+ else if ( pNode->IsTableNode() )
+ {
+ static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt()->
+ ResetFmtAttr( m_nWhich );
+ }
+}
+
+
+SwHistorySetTxt::SwHistorySetTxt( SwTxtAttr* pTxtHt, ULONG nNodePos )
+ : SwHistoryHint( HSTRY_SETTXTHNT )
+ , m_nNodeIndex( nNodePos )
+ , m_nStart( *pTxtHt->GetStart() )
+ , m_nEnd( *pTxtHt->GetAnyEnd() )
+{
+ // !! Achtung: folgende Attribute erzeugen keine FormatAttribute:
+ // - NoLineBreak, NoHypen, Inserted, Deleted
+ // Dafuer muessen Sonderbehandlungen gemacht werden !!!
+
+ // ein bisschen kompliziert, aber ist Ok so: erst vom default
+ // eine Kopie und dann die Werte aus dem Text Attribut zuweisen
+ USHORT nWhich = pTxtHt->Which();
+ if ( RES_TXTATR_CHARFMT == nWhich )
+ {
+ m_pAttr.reset( new SwFmtCharFmt( pTxtHt->GetCharFmt().GetCharFmt() ) );
+ }
+ else
+ {
+ m_pAttr.reset( pTxtHt->GetAttr().Clone() );
+ }
+}
+
+
+SwHistorySetTxt::~SwHistorySetTxt()
+{
+}
+
+
+void SwHistorySetTxt::SetInDoc( SwDoc* pDoc, bool )
+{
+ if ( !m_pAttr.get() )
+ return;
+
+ if ( RES_TXTATR_CHARFMT == m_pAttr->Which() )
+ {
+ // ask the Doc if the CharFmt still exists
+ if ( USHRT_MAX == pDoc->GetCharFmts()->GetPos(
+ (static_cast<SwFmtCharFmt&>(*m_pAttr)).GetCharFmt() ) )
+ return; // do not set, format does not exist
+ }
+
+ SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
+ ASSERT( pTxtNd, "SwHistorySetTxt::SetInDoc: not a TextNode" );
+
+ if ( pTxtNd )
+ {
+ pTxtNd->InsertItem( *m_pAttr, m_nStart, m_nEnd,
+ nsSetAttrMode::SETATTR_NOTXTATRCHR |
+ nsSetAttrMode::SETATTR_NOHINTADJUST );
+ }
+}
+
+
+SwHistorySetTxtFld::SwHistorySetTxtFld( SwTxtFld* pTxtFld, ULONG nNodePos )
+ : SwHistoryHint( HSTRY_SETTXTFLDHNT )
+ , m_pFldType( 0 )
+ , m_pFld( new SwFmtFld( *pTxtFld->GetFld().GetFld() ) )
+{
+ // only copy if not Sys-FieldType
+ SwDoc* pDoc = pTxtFld->GetTxtNode().GetDoc();
+
+ m_nFldWhich = m_pFld->GetFld()->GetTyp()->Which();
+ if (m_nFldWhich == RES_DBFLD ||
+ m_nFldWhich == RES_USERFLD ||
+ m_nFldWhich == RES_SETEXPFLD ||
+ m_nFldWhich == RES_DDEFLD ||
+ !pDoc->GetSysFldType( m_nFldWhich ))
+ {
+ m_pFldType.reset( m_pFld->GetFld()->GetTyp()->Copy() );
+ m_pFld->GetFld()->ChgTyp( m_pFldType.get() ); // change field type
+ }
+ m_nNodeIndex = nNodePos;
+ m_nPos = *pTxtFld->GetStart();
+}
+
+String SwHistorySetTxtFld::GetDescription() const
+{
+ return m_pFld->GetFld()->GetDescription();;
+}
+
+SwHistorySetTxtFld::~SwHistorySetTxtFld()
+{
+}
+
+
+void SwHistorySetTxtFld::SetInDoc( SwDoc* pDoc, bool )
+{
+ if ( !m_pFld.get() )
+ return;
+
+ SwFieldType* pNewFldType = m_pFldType.get();
+ if ( !pNewFldType )
+ {
+ pNewFldType = pDoc->GetSysFldType( m_nFldWhich );
+ }
+ else
+ {
+ // register type with the document
+ pNewFldType = pDoc->InsertFldType( *m_pFldType );
+ }
+
+ m_pFld->GetFld()->ChgTyp( pNewFldType ); // change field type
+
+ SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
+ ASSERT( pTxtNd, "SwHistorySetTxtFld: no TextNode" );
+
+ if ( pTxtNd )
+ {
+ pTxtNd->InsertItem( *m_pFld, m_nPos, m_nPos,
+ nsSetAttrMode::SETATTR_NOTXTATRCHR );
+ }
+}
+
+
+
+SwHistorySetRefMark::SwHistorySetRefMark( SwTxtRefMark* pTxtHt, ULONG nNodePos )
+ : SwHistoryHint( HSTRY_SETREFMARKHNT )
+ , m_RefName( pTxtHt->GetRefMark().GetRefName() )
+ , m_nNodeIndex( nNodePos )
+ , m_nStart( *pTxtHt->GetStart() )
+ , m_nEnd( *pTxtHt->GetAnyEnd() )
+{
+}
+
+
+void SwHistorySetRefMark::SetInDoc( SwDoc* pDoc, bool )
+{
+ SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
+ ASSERT( pTxtNd, "SwHistorySetRefMark: no TextNode" );
+ if ( !pTxtNd )
+ return;
+
+ SwFmtRefMark aRefMark( m_RefName );
+
+ // if a reference mark without an end already exists here: must not insert!
+ if ( m_nStart != m_nEnd ||
+ !pTxtNd->GetTxtAttrForCharAt( m_nStart, RES_TXTATR_REFMARK ) )
+ {
+ pTxtNd->InsertItem( aRefMark, m_nStart, m_nEnd,
+ nsSetAttrMode::SETATTR_NOTXTATRCHR );
+ }
+}
+
+
+SwHistorySetTOXMark::SwHistorySetTOXMark( SwTxtTOXMark* pTxtHt, ULONG nNodePos )
+ : SwHistoryHint( HSTRY_SETTOXMARKHNT )
+ , m_TOXMark( pTxtHt->GetTOXMark() )
+ , m_TOXName( m_TOXMark.GetTOXType()->GetTypeName() )
+ , m_eTOXTypes( m_TOXMark.GetTOXType()->GetType() )
+ , m_nNodeIndex( nNodePos )
+ , m_nStart( *pTxtHt->GetStart() )
+ , m_nEnd( *pTxtHt->GetAnyEnd() )
+{
+ const_cast<SwModify*>(m_TOXMark.GetRegisteredIn())->Remove( &m_TOXMark );
+}
+
+
+void SwHistorySetTOXMark::SetInDoc( SwDoc* pDoc, bool )
+{
+ SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
+ ASSERT( pTxtNd, "SwHistorySetTOXMark: no TextNode" );
+ if ( !pTxtNd )
+ return;
+
+ // search for respective TOX type
+ USHORT nCnt = pDoc->GetTOXTypeCount( m_eTOXTypes );
+ SwTOXType* pToxType = 0;
+ for ( USHORT n = 0; n < nCnt; ++n )
+ {
+ pToxType = const_cast<SwTOXType*>(pDoc->GetTOXType( m_eTOXTypes, n ));
+ if ( pToxType->GetTypeName() == m_TOXName )
+ break;
+ pToxType = 0;
+ }
+
+ if ( !pToxType ) // TOX type not found, create new
+ {
+ pToxType = const_cast<SwTOXType*>(
+ pDoc->InsertTOXType( SwTOXType( m_eTOXTypes, m_TOXName )));
+ }
+
+ SwTOXMark aNew( m_TOXMark );
+ pToxType->Add( &aNew );
+
+ pTxtNd->InsertItem( aNew, m_nStart, m_nEnd,
+ nsSetAttrMode::SETATTR_NOTXTATRCHR );
+}
+
+
+int SwHistorySetTOXMark::IsEqual( const SwTOXMark& rCmp ) const
+{
+ return m_TOXName == rCmp.GetTOXType()->GetTypeName() &&
+ m_eTOXTypes == rCmp.GetTOXType()->GetType() &&
+ m_TOXMark.GetAlternativeText() == rCmp.GetAlternativeText() &&
+ ( (TOX_INDEX == m_eTOXTypes)
+ ? ( m_TOXMark.GetPrimaryKey() == rCmp.GetPrimaryKey() &&
+ m_TOXMark.GetSecondaryKey() == rCmp.GetSecondaryKey() )
+ : m_TOXMark.GetLevel() == rCmp.GetLevel()
+ );
+}
+
+
+SwHistoryResetTxt::SwHistoryResetTxt( USHORT nWhich,
+ xub_StrLen nAttrStart, xub_StrLen nAttrEnd, ULONG nNodePos )
+ : SwHistoryHint( HSTRY_RESETTXTHNT )
+ , m_nNodeIndex( nNodePos ), m_nStart( nAttrStart ), m_nEnd( nAttrEnd )
+ , m_nAttr( nWhich )
+{
+}
+
+
+void SwHistoryResetTxt::SetInDoc( SwDoc* pDoc, bool )
+{
+ SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
+ ASSERT( pTxtNd, "SwHistoryResetTxt: no TextNode" );
+ if ( pTxtNd )
+ {
+ pTxtNd->DeleteAttributes( m_nAttr, m_nStart, m_nEnd );
+ }
+}
+
+
+SwHistorySetFootnote::SwHistorySetFootnote( SwTxtFtn* pTxtFtn, ULONG nNodePos )
+ : SwHistoryHint( HSTRY_SETFTNHNT )
+ , m_pUndo( new SwUndoSaveSection )
+ , m_FootnoteNumber( pTxtFtn->GetFtn().GetNumStr() )
+ , m_nNodeIndex( nNodePos )
+ , m_nStart( *pTxtFtn->GetStart() )
+ , m_bEndNote( pTxtFtn->GetFtn().IsEndNote() )
+{
+ ASSERT( pTxtFtn->GetStartNode(),
+ "SwHistorySetFootnote: Footnote without Section" );
+
+ // merke die alte NodePos, denn wer weiss was alles in der SaveSection
+ // gespeichert (geloescht) wird
+ SwDoc* pDoc = const_cast<SwDoc*>(pTxtFtn->GetTxtNode().GetDoc());
+ SwNode* pSaveNd = pDoc->GetNodes()[ m_nNodeIndex ];
+
+ //Pointer auf StartNode der FtnSection merken und erstmal den Pointer im
+ //Attribut zuruecksetzen -> Damit werden automatisch die Frms vernichtet.
+ SwNodeIndex aSttIdx( *pTxtFtn->GetStartNode() );
+ pTxtFtn->SetStartNode( 0, FALSE );
+
+ m_pUndo->SaveSection( pDoc, aSttIdx );
+ m_nNodeIndex = pSaveNd->GetIndex();
+}
+
+SwHistorySetFootnote::SwHistorySetFootnote( const SwTxtFtn &rTxtFtn )
+ : SwHistoryHint( HSTRY_SETFTNHNT )
+ , m_pUndo( 0 )
+ , m_FootnoteNumber( rTxtFtn.GetFtn().GetNumStr() )
+ , m_nNodeIndex( _SwTxtFtn_GetIndex( (&rTxtFtn) ) )
+ , m_nStart( *rTxtFtn.GetStart() )
+ , m_bEndNote( rTxtFtn.GetFtn().IsEndNote() )
+{
+ ASSERT( rTxtFtn.GetStartNode(),
+ "SwHistorySetFootnote: Footnote without Section" );
+}
+
+String SwHistorySetFootnote::GetDescription() const
+{
+ return SW_RES(STR_FOOTNOTE);
+}
+
+SwHistorySetFootnote::~SwHistorySetFootnote()
+{
+}
+
+
+void SwHistorySetFootnote::SetInDoc( SwDoc* pDoc, bool )
+{
+ SwTxtNode * pTxtNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetTxtNode();
+ ASSERT( pTxtNd, "SwHistorySetFootnote: no TextNode" );
+ if ( !pTxtNd )
+ return;
+
+ if ( m_pUndo.get() )
+ {
+ // set the footnote in the TextNode
+ SwFmtFtn aTemp( m_bEndNote );
+ SwFmtFtn& rNew = const_cast<SwFmtFtn&>(
+ static_cast<const SwFmtFtn&>(pDoc->GetAttrPool().Put(aTemp)) );
+ if ( m_FootnoteNumber.Len() )
+ {
+ rNew.SetNumStr( m_FootnoteNumber );
+ }
+ SwTxtFtn* pTxtFtn = new SwTxtFtn( rNew, m_nStart );
+
+ // create the section of the Footnote
+ SwNodeIndex aIdx( *pTxtNd );
+ m_pUndo->RestoreSection( pDoc, &aIdx, SwFootnoteStartNode );
+ pTxtFtn->SetStartNode( &aIdx );
+ if ( m_pUndo->GetHistory() )
+ {
+ // create frames only now
+ m_pUndo->GetHistory()->Rollback( pDoc );
+ }
+
+ pTxtNd->InsertHint( pTxtFtn );
+ }
+ else
+ {
+ SwTxtFtn * const pFtn =
+ const_cast<SwTxtFtn*>( static_cast<const SwTxtFtn*>(
+ pTxtNd->GetTxtAttrForCharAt( m_nStart )));
+ SwFmtFtn &rFtn = const_cast<SwFmtFtn&>(pFtn->GetFtn());
+ rFtn.SetNumStr( m_FootnoteNumber );
+ if ( rFtn.IsEndNote() != m_bEndNote )
+ {
+ rFtn.SetEndNote( m_bEndNote );
+ pFtn->CheckCondColl();
+ }
+ }
+}
+
+
+SwHistoryChangeFmtColl::SwHistoryChangeFmtColl( SwFmtColl* pFmtColl, ULONG nNd,
+ BYTE nNodeWhich )
+ : SwHistoryHint( HSTRY_CHGFMTCOLL )
+ , m_pColl( pFmtColl )
+ , m_nNodeIndex( nNd )
+ , m_nNodeType( nNodeWhich )
+{
+}
+
+void SwHistoryChangeFmtColl::SetInDoc( SwDoc* pDoc, bool )
+{
+ SwCntntNode * pCntntNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetCntntNode();
+ ASSERT( pCntntNd, "SwHistoryChangeFmtColl: no ContentNode" );
+
+ // before setting the format, check if it is still available in the
+ // document. if it has been deleted, there is no undo!
+ if ( pCntntNd && m_nNodeType == pCntntNd->GetNodeType() )
+ {
+ if ( ND_TEXTNODE == m_nNodeType )
+ {
+ if ( USHRT_MAX != pDoc->GetTxtFmtColls()->GetPos(
+ static_cast<SwTxtFmtColl * const>(m_pColl) ))
+ {
+ pCntntNd->ChgFmtColl( m_pColl );
+ }
+ }
+ else if ( USHRT_MAX != pDoc->GetGrfFmtColls()->GetPos(
+ static_cast<SwGrfFmtColl * const>(m_pColl) ))
+ {
+ pCntntNd->ChgFmtColl( m_pColl );
+ }
+ }
+}
+
+
+SwHistoryTxtFlyCnt::SwHistoryTxtFlyCnt( SwFrmFmt* const pFlyFmt )
+ : SwHistoryHint( HSTRY_FLYCNT )
+ , m_pUndo( new SwUndoDelLayFmt( pFlyFmt ) )
+{
+ ASSERT( pFlyFmt, "SwHistoryTxtFlyCnt: no Format" );
+ m_pUndo->ChgShowSel( FALSE );
+}
+
+
+SwHistoryTxtFlyCnt::~SwHistoryTxtFlyCnt()
+{
+}
+
+
+void SwHistoryTxtFlyCnt::SetInDoc( SwDoc* pDoc, bool )
+{
+ SwPaM aPam( pDoc->GetNodes().GetEndOfPostIts() );
+ SwUndoIter aUndoIter( &aPam );
+ m_pUndo->Undo( aUndoIter );
+}
+
+
+
+SwHistoryBookmark::SwHistoryBookmark(
+ const ::sw::mark::IMark& rBkmk,
+ bool bSavePos,
+ bool bSaveOtherPos)
+ : SwHistoryHint(HSTRY_BOOKMARK)
+ , m_aName(rBkmk.GetName())
+ , m_aShortName()
+ , m_aKeycode()
+ , m_nNode(bSavePos ?
+ rBkmk.GetMarkPos().nNode.GetIndex() : 0)
+ , m_nOtherNode(bSaveOtherPos ?
+ rBkmk.GetOtherMarkPos().nNode.GetIndex() : 0)
+ , m_nCntnt(bSavePos ?
+ rBkmk.GetMarkPos().nContent.GetIndex() : 0)
+ , m_nOtherCntnt(bSaveOtherPos ?
+ rBkmk.GetOtherMarkPos().nContent.GetIndex() :0)
+ , m_bSavePos(bSavePos)
+ , m_bSaveOtherPos(bSaveOtherPos)
+ , m_bHadOtherPos(rBkmk.IsExpanded())
+ , m_eBkmkType(IDocumentMarkAccess::GetType(rBkmk))
+{
+ const ::sw::mark::IBookmark* const pBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(&rBkmk);
+ if(pBookmark)
+ {
+ m_aKeycode = pBookmark->GetKeyCode();
+ m_aShortName = pBookmark->GetShortName();
+
+ ::sfx2::Metadatable const*const pMetadatable(
+ dynamic_cast< ::sfx2::Metadatable const* >(pBookmark));
+ if (pMetadatable)
+ {
+ m_pMetadataUndo = pMetadatable->CreateUndo();
+ }
+ }
+}
+
+
+void SwHistoryBookmark::SetInDoc( SwDoc* pDoc, bool )
+{
+ bool bDoesUndo = pDoc->DoesUndo();
+ pDoc->DoUndo(false);
+
+ SwNodes& rNds = pDoc->GetNodes();
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ ::std::auto_ptr<SwPaM> pPam;
+ ::sw::mark::IMark* pMark = NULL;
+
+ if(m_bSavePos)
+ {
+ SwCntntNode* const pCntntNd = rNds[m_nNode]->GetCntntNode();
+ OSL_ENSURE(pCntntNd,
+ "<SwHistoryBookmark::SetInDoc(..)>"
+ " - wrong node for a mark");
+
+ // #111660# don't crash when nNode1 doesn't point to content node.
+ if(pCntntNd)
+ pPam = ::std::auto_ptr<SwPaM>(new SwPaM(*pCntntNd, m_nCntnt));
+ }
+ else
+ {
+ pMark = pMarkAccess->findMark(m_aName)->get();
+ pPam = ::std::auto_ptr<SwPaM>(new SwPaM(pMark->GetMarkPos()));
+ }
+
+ if(m_bSaveOtherPos)
+ {
+ SwCntntNode* const pCntntNd = rNds[m_nOtherNode]->GetCntntNode();
+ OSL_ENSURE(pCntntNd,
+ "<SwHistoryBookmark::SetInDoc(..)>"
+ " - wrong node for a mark");
+
+ if(pPam.get() != NULL && pCntntNd)
+ {
+ pPam->SetMark();
+ pPam->GetMark()->nNode = m_nOtherNode;
+ pPam->GetMark()->nContent.Assign(pCntntNd, m_nOtherCntnt);
+ }
+ }
+ else if(m_bHadOtherPos)
+ {
+ if(!pMark)
+ pMark = pMarkAccess->findMark(m_aName)->get();
+ OSL_ENSURE(pMark->IsExpanded(),
+ "<SwHistoryBookmark::SetInDoc(..)>"
+ " - missing pos on old mark");
+ pPam->SetMark();
+ *pPam->GetMark() = pMark->GetOtherMarkPos();
+ }
+
+ if(pPam.get())
+ {
+ if(pMark)
+ pMarkAccess->deleteMark(pMark);
+ ::sw::mark::IBookmark* const pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(
+ pMarkAccess->makeMark(*pPam, m_aName, m_eBkmkType));
+ if(pBookmark)
+ {
+ pBookmark->SetKeyCode(m_aKeycode);
+ pBookmark->SetShortName(m_aShortName);
+ if (m_pMetadataUndo)
+ {
+ ::sfx2::Metadatable * const pMeta(
+ dynamic_cast< ::sfx2::Metadatable* >(pBookmark));
+ OSL_ENSURE(pMeta, "metadata undo, but not metadatable?");
+ if (pMeta)
+ {
+ pMeta->RestoreMetadata(m_pMetadataUndo);
+ }
+ }
+ }
+ }
+ pDoc->DoUndo(bDoesUndo);
+}
+
+
+bool SwHistoryBookmark::IsEqualBookmark(const ::sw::mark::IMark& rBkmk)
+{
+ return m_nNode == rBkmk.GetMarkPos().nNode.GetIndex()
+ && m_nCntnt == rBkmk.GetMarkPos().nContent.GetIndex()
+ && m_aName == rBkmk.GetName();
+}
+
+const ::rtl::OUString& SwHistoryBookmark::GetName() const
+{
+ return m_aName;
+}
+
+/*************************************************************************/
+
+
+SwHistorySetAttrSet::SwHistorySetAttrSet( const SfxItemSet& rSet,
+ ULONG nNodePos, const SvUShortsSort& rSetArr )
+ : SwHistoryHint( HSTRY_SETATTRSET )
+ , m_OldSet( rSet )
+ , m_ResetArray( 0, 4 )
+ , m_nNodeIndex( nNodePos )
+{
+ SfxItemIter aIter( m_OldSet ), aOrigIter( rSet );
+ const SfxPoolItem* pItem = aIter.FirstItem(),
+ * pOrigItem = aOrigIter.FirstItem();
+ do {
+ if( !rSetArr.Seek_Entry( pOrigItem->Which() ))
+ {
+ m_ResetArray.Insert( pOrigItem->Which(), m_ResetArray.Count() );
+ m_OldSet.ClearItem( pOrigItem->Which() );
+ }
+ else
+ {
+ switch ( pItem->Which() )
+ {
+ case RES_PAGEDESC:
+ static_cast<SwFmtPageDesc*>(
+ const_cast<SfxPoolItem*>(pItem))->ChgDefinedIn( 0 );
+ break;
+
+ case RES_PARATR_DROP:
+ static_cast<SwFmtDrop*>(
+ const_cast<SfxPoolItem*>(pItem))->ChgDefinedIn( 0 );
+ break;
+
+ case RES_BOXATR_FORMULA:
+ {
+ //JP 20.04.98: Bug 49502 - wenn eine Formel gesetzt ist, nie den
+ // Value mit sichern. Der muss gegebenfalls neu
+ // errechnet werden!
+ //JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
+ m_OldSet.ClearItem( RES_BOXATR_VALUE );
+
+ SwTblBoxFormula& rNew =
+ *static_cast<SwTblBoxFormula*>(
+ const_cast<SfxPoolItem*>(pItem));
+ if ( rNew.IsIntrnlName() )
+ {
+ const SwTblBoxFormula& rOld =
+ static_cast<const SwTblBoxFormula&>(
+ rSet.Get( RES_BOXATR_FORMULA ));
+ const SwNode* pNd = rOld.GetNodeOfFormula();
+ if ( pNd )
+ {
+ const SwTableNode* pTableNode
+ = pNd->FindTableNode();
+ if (pTableNode)
+ {
+ SwTableFmlUpdate aMsgHnt(
+ &pTableNode->GetTable() );
+ aMsgHnt.eFlags = TBL_BOXNAME;
+ rNew.ChgDefinedIn( rOld.GetDefinedIn() );
+ rNew.ChangeState( &aMsgHnt );
+ }
+ }
+ }
+ rNew.ChgDefinedIn( 0 );
+ }
+ break;
+ }
+ }
+
+ if( aIter.IsAtEnd() )
+ break;
+ pItem = aIter.NextItem();
+ pOrigItem = aOrigIter.NextItem();
+ } while( TRUE );
+}
+
+void SwHistorySetAttrSet::SetInDoc( SwDoc* pDoc, bool )
+{
+ BOOL bDoesUndo = pDoc->DoesUndo();
+ pDoc->DoUndo( FALSE );
+
+ SwNode * pNode = pDoc->GetNodes()[ m_nNodeIndex ];
+ if ( pNode->IsCntntNode() )
+ {
+ static_cast<SwCntntNode*>(pNode)->SetAttr( m_OldSet );
+ if ( m_ResetArray.Count() )
+ {
+ static_cast<SwCntntNode*>(pNode)->ResetAttr( m_ResetArray );
+ }
+ }
+ else if ( pNode->IsTableNode() )
+ {
+ SwFmt& rFmt =
+ *static_cast<SwTableNode*>(pNode)->GetTable().GetFrmFmt();
+ rFmt.SetFmtAttr( m_OldSet );
+ if ( m_ResetArray.Count() )
+ {
+ rFmt.ResetFmtAttr( *m_ResetArray.GetData() );
+ }
+ }
+
+ pDoc->DoUndo( bDoesUndo );
+}
+
+/*************************************************************************/
+
+
+SwHistoryResetAttrSet::SwHistoryResetAttrSet( const SfxItemSet& rSet,
+ ULONG nNodePos, xub_StrLen nAttrStt, xub_StrLen nAttrEnd )
+ : SwHistoryHint( HSTRY_RESETATTRSET )
+ , m_nNodeIndex( nNodePos ), m_nStart( nAttrStt ), m_nEnd( nAttrEnd )
+ , m_Array( (BYTE)rSet.Count() )
+{
+ SfxItemIter aIter( rSet );
+ bool bAutoStyle = false;
+
+ while( TRUE )
+ {
+ const USHORT nWhich = aIter.GetCurItem()->Which();
+
+#ifndef PRODUCT
+ switch (nWhich)
+ {
+ case RES_TXTATR_REFMARK:
+ case RES_TXTATR_TOXMARK:
+ if (m_nStart != m_nEnd) break; // else: fall through!
+ case RES_TXTATR_FIELD:
+ case RES_TXTATR_FLYCNT:
+ case RES_TXTATR_FTN:
+ case RES_TXTATR_META:
+ case RES_TXTATR_METAFIELD:
+ ASSERT(rSet.Count() == 1,
+ "text attribute with CH_TXTATR, but not the only one:"
+ "\nnot such a good idea");
+ break;
+ }
+#endif
+
+ // Character attribute cannot be inserted into the hints array
+ // anymore. Therefore we have to treat them as one RES_TXTATR_AUTOFMT:
+ if (isCHRATR(nWhich))
+ {
+ bAutoStyle = true;
+ }
+ else
+ {
+ m_Array.Insert( aIter.GetCurItem()->Which(), m_Array.Count() );
+ }
+
+ if( aIter.IsAtEnd() )
+ break;
+
+ aIter.NextItem();
+ }
+
+ if ( bAutoStyle )
+ {
+ m_Array.Insert( RES_TXTATR_AUTOFMT, m_Array.Count() );
+ }
+}
+
+
+void SwHistoryResetAttrSet::SetInDoc( SwDoc* pDoc, bool )
+{
+ BOOL bDoesUndo = pDoc->DoesUndo();
+ pDoc->DoUndo( FALSE );
+
+ SwCntntNode * pCntntNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetCntntNode();
+ ASSERT( pCntntNd, "SwHistoryResetAttrSet: no CntntNode" );
+
+ if (pCntntNd)
+ {
+ const USHORT* pArr = m_Array.GetData();
+ if ( USHRT_MAX == m_nEnd && USHRT_MAX == m_nStart )
+ {
+ // no area: use ContentNode
+ for ( USHORT n = m_Array.Count(); n; --n, ++pArr )
+ {
+ pCntntNd->ResetAttr( *pArr );
+ }
+ }
+ else
+ {
+ // area: use TextNode
+ for ( USHORT n = m_Array.Count(); n; --n, ++pArr )
+ {
+ static_cast<SwTxtNode*>(pCntntNd)->
+ DeleteAttributes( *pArr, m_nStart, m_nEnd );
+ }
+ }
+ }
+
+ pDoc->DoUndo( bDoesUndo );
+}
+
+
+/*************************************************************************/
+
+
+SwHistoryChangeFlyAnchor::SwHistoryChangeFlyAnchor( SwFrmFmt& rFmt )
+ : SwHistoryHint( HSTRY_CHGFLYANCHOR )
+ , m_rFmt( rFmt )
+ , m_nOldNodeIndex( rFmt.GetAnchor().GetCntntAnchor()->nNode.GetIndex() )
+ , m_nOldContentIndex( (FLY_AT_CHAR == rFmt.GetAnchor().GetAnchorId())
+ ? rFmt.GetAnchor().GetCntntAnchor()->nContent.GetIndex()
+ : STRING_MAXLEN )
+{
+}
+
+
+void SwHistoryChangeFlyAnchor::SetInDoc( SwDoc* pDoc, bool )
+{
+ BOOL bDoesUndo = pDoc->DoesUndo();
+ pDoc->DoUndo( FALSE );
+
+ USHORT nPos = pDoc->GetSpzFrmFmts()->GetPos( &m_rFmt );
+ if ( USHRT_MAX != nPos ) // Format does still exist
+ {
+ SwFmtAnchor aTmp( m_rFmt.GetAnchor() );
+
+ SwNode* pNd = pDoc->GetNodes()[ m_nOldNodeIndex ];
+ SwCntntNode* pCNd = pNd->GetCntntNode();
+ SwPosition aPos( *pNd );
+ if ( STRING_MAXLEN != m_nOldContentIndex )
+ {
+ ASSERT(pCNd, "SwHistoryChangeFlyAnchor: no ContentNode");
+ if (pCNd)
+ {
+ aPos.nContent.Assign( pCNd, m_nOldContentIndex );
+ }
+ }
+ aTmp.SetAnchor( &aPos );
+
+ // so the Layout does not get confused
+ if ( !pCNd || !pCNd->GetFrm( 0, 0, FALSE ) )
+ {
+ m_rFmt.DelFrms();
+ }
+
+ m_rFmt.SetFmtAttr( aTmp );
+ }
+ pDoc->DoUndo( bDoesUndo );
+}
+
+
+/*************************************************************************/
+
+SwHistoryChangeFlyChain::SwHistoryChangeFlyChain( SwFlyFrmFmt& rFmt,
+ const SwFmtChain& rAttr )
+ : SwHistoryHint( HSTRY_CHGFLYCHAIN )
+ , m_pPrevFmt( rAttr.GetPrev() )
+ , m_pNextFmt( rAttr.GetNext() )
+ , m_pFlyFmt( &rFmt )
+{
+}
+
+
+void SwHistoryChangeFlyChain::SetInDoc( SwDoc* pDoc, bool )
+{
+ if ( USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pFlyFmt ) )
+ {
+ SwFmtChain aChain;
+
+ if ( m_pPrevFmt &&
+ USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pPrevFmt ) )
+ {
+ aChain.SetPrev( m_pPrevFmt );
+ SwFmtChain aTmp( m_pPrevFmt->GetChain() );
+ aTmp.SetNext( m_pFlyFmt );
+ m_pPrevFmt->SetFmtAttr( aTmp );
+ }
+
+ if ( m_pNextFmt &&
+ USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pNextFmt ) )
+ {
+ aChain.SetNext( m_pNextFmt );
+ SwFmtChain aTmp( m_pNextFmt->GetChain() );
+ aTmp.SetPrev( m_pFlyFmt );
+ m_pNextFmt->SetFmtAttr( aTmp );
+ }
+
+ if ( aChain.GetNext() || aChain.GetPrev() )
+ {
+ m_pFlyFmt->SetFmtAttr( aChain );
+ }
+ }
+}
+
+
+// -> #i27615#
+SwHistoryChangeCharFmt::SwHistoryChangeCharFmt(const SfxItemSet & rSet,
+ const String & sFmt)
+ : SwHistoryHint(HSTRY_CHGCHARFMT)
+ , m_OldSet(rSet), m_Fmt(sFmt)
+{
+}
+
+void SwHistoryChangeCharFmt::SetInDoc(SwDoc * pDoc, bool )
+{
+ SwCharFmt * pCharFmt = pDoc->FindCharFmtByName(m_Fmt);
+
+ if (pCharFmt)
+ {
+ pCharFmt->SetFmtAttr(m_OldSet);
+ }
+}
+// <- #i27615#
+
+/* */
+
+
+SwHistory::SwHistory( USHORT nInitSz, USHORT nGrowSz )
+ : m_SwpHstry( (BYTE)nInitSz, (BYTE)nGrowSz )
+ , m_nEndDiff( 0 )
+{}
+
+
+SwHistory::~SwHistory()
+{
+ Delete( 0 );
+}
+
+
+/*************************************************************************
+|*
+|* void SwHistory::Add()
+|*
+|* Beschreibung Dokument 1.0
+|* Ersterstellung JP 18.02.91
+|* Letzte Aenderung JP 18.02.91
+|*
+*************************************************************************/
+
+// --> OD 2008-02-27 #refactorlists# - removed <rDoc>
+void SwHistory::Add( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue,
+ ULONG nNodeIdx )
+// <--
+{
+ ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
+
+ USHORT nWhich = pNewValue->Which();
+ if( (nWhich >= POOLATTR_END) || (nWhich == RES_TXTATR_FIELD) )
+ return;
+
+ // no default Attribute?
+ SwHistoryHint * pHt;
+ if ( pOldValue && pOldValue != GetDfltAttr( pOldValue->Which() ) )
+ {
+ pHt = new SwHistorySetFmt( pOldValue, nNodeIdx );
+ }
+ else
+ {
+ pHt = new SwHistoryResetFmt( pNewValue, nNodeIdx );
+ }
+ m_SwpHstry.Insert( pHt, Count() );
+}
+
+
+void SwHistory::Add( SwTxtAttr* pHint, ULONG nNodeIdx, bool bNewAttr )
+{
+ ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
+
+ SwHistoryHint * pHt;
+ USHORT nAttrWhich = pHint->Which();
+
+ if( !bNewAttr )
+ {
+ switch ( nAttrWhich )
+ {
+ case RES_TXTATR_FTN:
+ pHt = new SwHistorySetFootnote(
+ static_cast<SwTxtFtn*>(pHint), nNodeIdx );
+ break;
+ case RES_TXTATR_FLYCNT:
+ pHt = new SwHistoryTxtFlyCnt( static_cast<SwTxtFlyCnt*>(pHint)
+ ->GetFlyCnt().GetFrmFmt() );
+ break;
+ case RES_TXTATR_FIELD:
+ pHt = new SwHistorySetTxtFld(
+ static_cast<SwTxtFld*>(pHint), nNodeIdx );
+ break;
+ case RES_TXTATR_TOXMARK:
+ pHt = new SwHistorySetTOXMark(
+ static_cast<SwTxtTOXMark*>(pHint), nNodeIdx );
+ break;
+ case RES_TXTATR_REFMARK:
+ pHt = new SwHistorySetRefMark(
+ static_cast<SwTxtRefMark*>(pHint), nNodeIdx );
+ break;
+ default:
+ pHt = new SwHistorySetTxt(
+ static_cast<SwTxtAttr*>(pHint), nNodeIdx );
+ }
+ }
+ else
+ {
+ pHt = new SwHistoryResetTxt( pHint->Which(), *pHint->GetStart(),
+ *pHint->GetAnyEnd(), nNodeIdx );
+ }
+ m_SwpHstry.Insert( pHt, Count() );
+}
+
+
+void SwHistory::Add( SwFmtColl* pColl, ULONG nNodeIdx, BYTE nWhichNd )
+{
+ ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
+
+ SwHistoryHint * pHt =
+ new SwHistoryChangeFmtColl( pColl, nNodeIdx, nWhichNd );
+ m_SwpHstry.Insert( pHt, Count() );
+}
+
+
+void SwHistory::Add(const ::sw::mark::IMark& rBkmk, bool bSavePos, bool bSaveOtherPos)
+{
+ ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
+
+ SwHistoryHint * pHt = new SwHistoryBookmark(rBkmk, bSavePos, bSaveOtherPos);
+ m_SwpHstry.Insert( pHt, Count() );
+}
+
+
+void SwHistory::Add( SwFrmFmt& rFmt )
+{
+ SwHistoryHint * pHt = new SwHistoryChangeFlyAnchor( rFmt );
+ m_SwpHstry.Insert( pHt, Count() );
+}
+
+void SwHistory::Add( SwFlyFrmFmt& rFmt, USHORT& rSetPos )
+{
+ ASSERT( !m_nEndDiff, "History was not deleted after REDO" );
+
+ SwHistoryHint * pHint;
+ const USHORT nWh = rFmt.Which();
+ if( RES_FLYFRMFMT == nWh || RES_DRAWFRMFMT == nWh )
+ {
+ pHint = new SwHistoryTxtFlyCnt( &rFmt );
+ m_SwpHstry.Insert( pHint, Count() );
+
+ const SwFmtChain* pChainItem;
+ if( SFX_ITEM_SET == rFmt.GetItemState( RES_CHAIN, FALSE,
+ (const SfxPoolItem**)&pChainItem ))
+ {
+ if( pChainItem->GetNext() || pChainItem->GetPrev() )
+ {
+ SwHistoryHint * pHt =
+ new SwHistoryChangeFlyChain( rFmt, *pChainItem );
+ m_SwpHstry.Insert( pHt, rSetPos++ );
+ if ( pChainItem->GetNext() )
+ {
+ SwFmtChain aTmp( pChainItem->GetNext()->GetChain() );
+ aTmp.SetPrev( 0 );
+ pChainItem->GetNext()->SetFmtAttr( aTmp );
+ }
+ if ( pChainItem->GetPrev() )
+ {
+ SwFmtChain aTmp( pChainItem->GetPrev()->GetChain() );
+ aTmp.SetNext( 0 );
+ pChainItem->GetPrev()->SetFmtAttr( aTmp );
+ }
+ }
+ rFmt.ResetFmtAttr( RES_CHAIN );
+ }
+ }
+}
+
+void SwHistory::Add( const SwTxtFtn& rFtn )
+{
+ SwHistoryHint *pHt = new SwHistorySetFootnote( rFtn );
+ m_SwpHstry.Insert( pHt, Count() );
+}
+
+// #i27615#
+void SwHistory::Add(const SfxItemSet & rSet, const SwCharFmt & rFmt)
+{
+ SwHistoryHint * pHt = new SwHistoryChangeCharFmt(rSet, rFmt.GetName());
+ m_SwpHstry.Insert(pHt, Count());
+}
+
+/*************************************************************************
+|*
+|* BOOL SwHistory::Rollback()
+|*
+|* Beschreibung Dokument 1.0
+|* Ersterstellung JP 18.02.91
+|* Letzte Aenderung JP 18.02.91
+|*
+*************************************************************************/
+
+
+bool SwHistory::Rollback( SwDoc* pDoc, USHORT nStart )
+{
+ if ( !Count() )
+ return false;
+
+ SwHistoryHint * pHHt;
+ USHORT i;
+ for ( i = Count(); i > nStart ; )
+ {
+ pHHt = m_SwpHstry[ --i ];
+ pHHt->SetInDoc( pDoc, false );
+ delete pHHt;
+ }
+ m_SwpHstry.Remove( nStart, Count() - nStart );
+ m_nEndDiff = 0;
+ return true;
+}
+
+
+
+bool SwHistory::TmpRollback( SwDoc* pDoc, USHORT nStart, bool bToFirst )
+{
+ USHORT nEnd = Count() - m_nEndDiff;
+ if ( !Count() || !nEnd || nStart >= nEnd )
+ return false;
+
+ SwHistoryHint * pHHt;
+ if ( bToFirst )
+ {
+ for ( ; nEnd > nStart; ++m_nEndDiff )
+ {
+ pHHt = m_SwpHstry[ --nEnd ];
+ pHHt->SetInDoc( pDoc, true );
+ }
+ }
+ else
+ {
+ for ( ; nStart < nEnd; ++m_nEndDiff, ++nStart )
+ {
+ pHHt = m_SwpHstry[ nStart ];
+ pHHt->SetInDoc( pDoc, true );
+ }
+ }
+ return true;
+}
+
+
+void SwHistory::Delete( USHORT nStart )
+{
+ for ( USHORT n = Count(); n > nStart; )
+ {
+ m_SwpHstry.DeleteAndDestroy( --n, 1 );
+ }
+ m_nEndDiff = 0;
+}
+
+
+USHORT SwHistory::SetTmpEnd( USHORT nNewTmpEnd )
+{
+ ASSERT( nNewTmpEnd <= Count(), "SwHistory::SetTmpEnd: out of bounds" );
+
+ USHORT nOld = Count() - m_nEndDiff;
+ m_nEndDiff = Count() - nNewTmpEnd;
+
+ // for every SwHistoryFlyCnt, call the Redo of its UndoObject.
+ // this saves the formats of the flys!
+ for ( USHORT n = nOld; n < nNewTmpEnd; n++ )
+ {
+ if ( HSTRY_FLYCNT == (*this)[ n ]->Which() )
+ {
+ static_cast<SwHistoryTxtFlyCnt*>((*this)[ n ])
+ ->GetUDelLFmt()->Redo();
+ }
+ }
+
+ return nOld;
+}
+
+void SwHistory::CopyFmtAttr( const SfxItemSet& rSet, ULONG nNodeIdx )
+{
+ if( rSet.Count() )
+ {
+ SfxItemIter aIter( rSet );
+ do {
+ if( (SfxPoolItem*)-1 != aIter.GetCurItem() )
+ {
+ const SfxPoolItem* pNew = aIter.GetCurItem();
+ Add( pNew, pNew, nNodeIdx );
+ }
+ if( aIter.IsAtEnd() )
+ break;
+ aIter.NextItem();
+ } while( TRUE );
+ }
+}
+
+void SwHistory::CopyAttr( SwpHints* pHts, ULONG nNodeIdx,
+ xub_StrLen nStart, xub_StrLen nEnd, bool bFields )
+{
+ if( !pHts )
+ return;
+
+ // copy all attributes of the TextNode in the area from nStart to nEnd
+ SwTxtAttr* pHt;
+ xub_StrLen nAttrStt;
+ const xub_StrLen * pEndIdx;
+ for( USHORT n = 0; n < pHts->Count(); n++ )
+ {
+ // BP: nAttrStt muss auch bei !pEndIdx gesetzt werden
+ pHt = pHts->GetTextHint(n);
+ nAttrStt = *pHt->GetStart();
+// JP: ???? wieso nAttrStt >= nEnd
+// if( 0 != ( pEndIdx = pHt->GetEnd() ) && nAttrStt >= nEnd )
+ if( 0 != ( pEndIdx = pHt->GetEnd() ) && nAttrStt > nEnd )
+ break;
+
+ // Flys und Ftn nie kopieren !!
+ BOOL bNextAttr = FALSE;
+ switch( pHt->Which() )
+ {
+ case RES_TXTATR_FIELD:
+ // keine Felder, .. kopieren ??
+ if( !bFields )
+ bNextAttr = TRUE;
+ break;
+ case RES_TXTATR_FLYCNT:
+ case RES_TXTATR_FTN:
+ bNextAttr = TRUE;
+ break;
+ }
+
+ if( bNextAttr )
+ continue;
+
+ // save all attributes that are somehow in this area
+ if ( nStart <= nAttrStt )
+ {
+ if ( nEnd > nAttrStt
+// JP: ???? wieso nAttrStt >= nEnd
+// || (nEnd == nAttrStt && (!pEndIdx || nEnd == pEndIdx->GetIndex()))
+ )
+ {
+ Add( pHt, nNodeIdx, false );
+ }
+ }
+ else if ( pEndIdx && nStart < *pEndIdx )
+ {
+ Add( pHt, nNodeIdx, false );
+ }
+ }
+}
+
+
+/*************************************************************************/
+
+// Klasse zum Registrieren der History am Node, Format, HintsArray, ...
+
+SwRegHistory::SwRegHistory( SwHistory* pHst )
+ : SwClient( 0 )
+ , m_pHistory( pHst )
+ , m_nNodeIndex( ULONG_MAX )
+{
+ _MakeSetWhichIds();
+}
+
+SwRegHistory::SwRegHistory( SwModify* pRegIn, const SwNode& rNd,
+ SwHistory* pHst )
+ : SwClient( pRegIn )
+ , m_pHistory( pHst )
+ , m_nNodeIndex( rNd.GetIndex() )
+{
+ _MakeSetWhichIds();
+}
+
+SwRegHistory::SwRegHistory( const SwNode& rNd, SwHistory* pHst )
+ : SwClient( 0 )
+ , m_pHistory( pHst )
+ , m_nNodeIndex( rNd.GetIndex() )
+{
+ _MakeSetWhichIds();
+}
+
+void SwRegHistory::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew )
+{
+ if ( m_pHistory && ( pOld || pNew ) )
+ {
+ if ( pNew->Which() < POOLATTR_END )
+ {
+ m_pHistory->Add( pOld, pNew, m_nNodeIndex );
+ }
+ else if ( RES_ATTRSET_CHG == pNew->Which() )
+ {
+ SwHistoryHint* pNewHstr;
+ const SfxItemSet& rSet =
+ *static_cast<SwAttrSetChg*>(pOld)->GetChgSet();
+ if ( 1 < rSet.Count() )
+ {
+ pNewHstr =
+ new SwHistorySetAttrSet( rSet, m_nNodeIndex, m_WhichIdSet );
+ }
+ else
+ {
+ const SfxPoolItem* pItem = SfxItemIter( rSet ).FirstItem();
+ if ( m_WhichIdSet.Seek_Entry( pItem->Which() ) )
+ {
+ pNewHstr = new SwHistorySetFmt( pItem, m_nNodeIndex );
+ }
+ else
+ {
+ pNewHstr = new SwHistoryResetFmt( pItem, m_nNodeIndex );
+ }
+ }
+ m_pHistory->m_SwpHstry.Insert( pNewHstr, m_pHistory->Count() );
+ }
+ }
+}
+
+
+
+void SwRegHistory::AddHint( SwTxtAttr* pHt, const bool bNew )
+{
+ m_pHistory->Add( pHt, m_nNodeIndex, bNew );
+}
+
+
+bool SwRegHistory::InsertItems( const SfxItemSet& rSet,
+ xub_StrLen const nStart, xub_StrLen const nEnd, SetAttrMode const nFlags )
+{
+ if( !rSet.Count() )
+ return false;
+
+ SwTxtNode * const pTxtNode =
+ dynamic_cast<SwTxtNode *>(const_cast<SwModify *>(GetRegisteredIn()));
+
+ ASSERT(pTxtNode, "SwRegHistory not registered at text node?");
+ if (!pTxtNode)
+ return false;
+
+ if ( pTxtNode->GetpSwpHints() && m_pHistory )
+ {
+ pTxtNode->GetpSwpHints()->Register( this );
+ }
+
+ const bool bInserted = pTxtNode->SetAttr( rSet, nStart, nEnd, nFlags );
+
+ // Achtung: Durch das Einfuegen eines Attributs kann das Array
+ // geloescht werden!!! Wenn das einzufuegende zunaechst ein vorhandenes
+ // loescht, selbst aber nicht eingefuegt werden braucht, weil die
+ // Absatzattribute identisch sind( -> bForgetAttr in SwpHints::Insert )
+ if ( pTxtNode->GetpSwpHints() && m_pHistory )
+ {
+ pTxtNode->GetpSwpHints()->DeRegister();
+ }
+
+ if ( m_pHistory && bInserted )
+ {
+ SwHistoryHint* pNewHstr = new SwHistoryResetAttrSet( rSet,
+ pTxtNode->GetIndex(), nStart, nEnd );
+ // der NodeIndex kann verschoben sein !!
+
+ m_pHistory->m_SwpHstry.Insert( pNewHstr, m_pHistory->Count() );
+ }
+
+ return bInserted;
+}
+
+void SwRegHistory::RegisterInModify( SwModify* pRegIn, const SwNode& rNd )
+{
+ if ( m_pHistory && pRegIn )
+ {
+ pRegIn->Add( this );
+ m_nNodeIndex = rNd.GetIndex();
+ _MakeSetWhichIds();
+ }
+ else if ( m_WhichIdSet.Count() )
+ {
+ m_WhichIdSet.Remove( 0, m_WhichIdSet.Count() );
+ }
+}
+
+void SwRegHistory::_MakeSetWhichIds()
+{
+ if (!m_pHistory) return;
+
+ if ( m_WhichIdSet.Count() )
+ {
+ m_WhichIdSet.Remove( 0, m_WhichIdSet.Count() );
+ }
+
+ if( GetRegisteredIn() )
+ {
+ const SfxItemSet* pSet = 0;
+ if( GetRegisteredIn()->ISA( SwCntntNode ) )
+ {
+ pSet = static_cast<SwCntntNode*>(
+ const_cast<SwModify*>(GetRegisteredIn()))->GetpSwAttrSet();
+ }
+ else if ( GetRegisteredIn()->ISA( SwFmt ) )
+ {
+ pSet = &static_cast<SwFmt*>(
+ const_cast<SwModify*>(GetRegisteredIn()))->GetAttrSet();
+ }
+ if( pSet && pSet->Count() )
+ {
+ SfxItemIter aIter( *pSet );
+ USHORT nW = aIter.FirstItem()->Which();
+ while( TRUE )
+ {
+ m_WhichIdSet.Insert( nW );
+ if( aIter.IsAtEnd() )
+ break;
+ nW = aIter.NextItem()->Which();
+ }
+ }
+ }
+}
+