| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sw.hxx" |
| |
| #include <rolbck.hxx> |
| |
| #include <tools/resid.hxx> |
| |
| #include <svl/itemiter.hxx> |
| |
| #include <editeng/brkitem.hxx> |
| |
| #include <hints.hxx> |
| #include <hintids.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 <IDocumentUndoRedo.hxx> |
| #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 <ndgrf.hxx> // SwGrfNode |
| #include <UndoCore.hxx> |
| #include <IMark.hxx> // fuer SwBookmark |
| #include <charfmt.hxx> // #i27615# |
| #include <comcore.hrc> |
| #include <undo.hrc> |
| #include <bookmrk.hxx> |
| |
| SV_IMPL_PTRARR( SwpHstry, SwHistoryHintPtr) |
| |
| String SwHistoryHint::GetDescription() const |
| { |
| return String(); |
| } |
| |
| |
| SwHistorySetFmt::SwHistorySetFmt( const SfxPoolItem* pFmtHt, sal_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 ; |
| |
| sal_uInt16 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, sal_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, sal_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 |
| sal_uInt16 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, sal_uLong nNodePos ) |
| : SwHistoryHint( HSTRY_SETTXTFLDHNT ) |
| , m_pFldType( 0 ) |
| , m_pFld( new SwFmtFld( *pTxtFld->GetFmtFld().GetField() ) ) |
| { |
| // only copy if not Sys-FieldType |
| SwDoc* pDoc = pTxtFld->GetTxtNode().GetDoc(); |
| |
| m_nFldWhich = m_pFld->GetField()->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->GetField()->GetTyp()->Copy() ); |
| m_pFld->GetField()->ChgTyp( m_pFldType.get() ); // change field type |
| } |
| m_nNodeIndex = nNodePos; |
| m_nPos = *pTxtFld->GetStart(); |
| } |
| |
| String SwHistorySetTxtFld::GetDescription() const |
| { |
| return m_pFld->GetField()->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->GetField()->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, sal_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, sal_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() ) |
| { |
| m_TOXMark.DeRegister(); |
| } |
| |
| |
| 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 |
| sal_uInt16 nCnt = pDoc->GetTOXTypeCount( m_eTOXTypes ); |
| SwTOXType* pToxType = 0; |
| for ( sal_uInt16 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 ); |
| aNew.RegisterToTOXType( *pToxType ); |
| |
| 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( sal_uInt16 nWhich, |
| xub_StrLen nAttrStart, xub_StrLen nAttrEnd, sal_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, sal_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, sal_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, sal_uLong nNd, |
| sal_uInt8 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( sal_False ); |
| } |
| |
| |
| SwHistoryTxtFlyCnt::~SwHistoryTxtFlyCnt() |
| { |
| } |
| |
| |
| void SwHistoryTxtFlyCnt::SetInDoc( SwDoc* pDoc, bool ) |
| { |
| ::sw::IShellCursorSupplier *const pISCS(pDoc->GetIShellCursorSupplier()); |
| OSL_ASSERT(pISCS); |
| ::sw::UndoRedoContext context(*pDoc, *pISCS); |
| m_pUndo->UndoImpl(context); |
| } |
| |
| |
| |
| 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 ) |
| { |
| ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo()); |
| |
| 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 != NULL ) |
| { |
| pMarkAccess->deleteMark( pMark ); |
| } |
| ::sw::mark::IBookmark* const pBookmark = |
| dynamic_cast< ::sw::mark::IBookmark* >( pMarkAccess->makeMark(*pPam, m_aName, m_eBkmkType) ); |
| if ( pBookmark != NULL ) |
| { |
| 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); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| 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, |
| sal_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( sal_True ); |
| } |
| |
| void SwHistorySetAttrSet::SetInDoc( SwDoc* pDoc, bool ) |
| { |
| ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo()); |
| |
| 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() ); |
| } |
| } |
| } |
| |
| /*************************************************************************/ |
| |
| |
| SwHistoryResetAttrSet::SwHistoryResetAttrSet( const SfxItemSet& rSet, |
| sal_uLong nNodePos, xub_StrLen nAttrStt, xub_StrLen nAttrEnd ) |
| : SwHistoryHint( HSTRY_RESETATTRSET ) |
| , m_nNodeIndex( nNodePos ), m_nStart( nAttrStt ), m_nEnd( nAttrEnd ) |
| , m_Array( (sal_uInt8)rSet.Count() ) |
| { |
| SfxItemIter aIter( rSet ); |
| bool bAutoStyle = false; |
| |
| while( sal_True ) |
| { |
| const sal_uInt16 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_ANNOTATION: |
| 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 ) |
| { |
| ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo()); |
| |
| SwCntntNode * pCntntNd = pDoc->GetNodes()[ m_nNodeIndex ]->GetCntntNode(); |
| ASSERT( pCntntNd, "SwHistoryResetAttrSet: no CntntNode" ); |
| |
| if (pCntntNd) |
| { |
| const sal_uInt16* pArr = m_Array.GetData(); |
| if ( USHRT_MAX == m_nEnd && USHRT_MAX == m_nStart ) |
| { |
| // no area: use ContentNode |
| for ( sal_uInt16 n = m_Array.Count(); n; --n, ++pArr ) |
| { |
| pCntntNd->ResetAttr( *pArr ); |
| } |
| } |
| else |
| { |
| // area: use TextNode |
| for ( sal_uInt16 n = m_Array.Count(); n; --n, ++pArr ) |
| { |
| static_cast<SwTxtNode*>(pCntntNd)-> |
| DeleteAttributes( *pArr, m_nStart, m_nEnd ); |
| } |
| } |
| } |
| } |
| |
| |
| /*************************************************************************/ |
| |
| |
| 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 ) |
| { |
| ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo()); |
| |
| sal_uInt16 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->getLayoutFrm( pDoc->GetCurrentLayout(), 0, 0, sal_False ) ) |
| { |
| m_rFmt.DelFrms(); |
| } |
| |
| m_rFmt.SetFmtAttr( aTmp ); |
| } |
| } |
| |
| |
| /*************************************************************************/ |
| |
| 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( sal_uInt16 nInitSz, sal_uInt16 nGrowSz ) |
| : m_SwpHstry( (sal_uInt8)nInitSz, (sal_uInt8)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 |
| |* |
| *************************************************************************/ |
| |
| void SwHistory::Add( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue, |
| sal_uLong nNodeIdx ) |
| { |
| ASSERT( !m_nEndDiff, "History was not deleted after REDO" ); |
| |
| sal_uInt16 nWhich = pNewValue->Which(); |
| if( (nWhich >= POOLATTR_END) |
| || (nWhich == RES_TXTATR_FIELD) |
| || (nWhich == RES_TXTATR_ANNOTATION) ) |
| 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, sal_uLong nNodeIdx, bool bNewAttr ) |
| { |
| ASSERT( !m_nEndDiff, "History was not deleted after REDO" ); |
| |
| SwHistoryHint * pHt; |
| sal_uInt16 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: |
| case RES_TXTATR_ANNOTATION: |
| 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, sal_uLong nNodeIdx, sal_uInt8 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, sal_uInt16& rSetPos ) |
| { |
| ASSERT( !m_nEndDiff, "History was not deleted after REDO" ); |
| |
| SwHistoryHint * pHint; |
| const sal_uInt16 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, sal_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()); |
| } |
| |
| /************************************************************************* |
| |* |
| |* sal_Bool SwHistory::Rollback() |
| |* |
| |* Beschreibung Dokument 1.0 |
| |* Ersterstellung JP 18.02.91 |
| |* Letzte Aenderung JP 18.02.91 |
| |* |
| *************************************************************************/ |
| |
| |
| bool SwHistory::Rollback( SwDoc* pDoc, sal_uInt16 nStart ) |
| { |
| if ( !Count() ) |
| return false; |
| |
| SwHistoryHint * pHHt; |
| sal_uInt16 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, sal_uInt16 nStart, bool bToFirst ) |
| { |
| sal_uInt16 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( sal_uInt16 nStart ) |
| { |
| for ( sal_uInt16 n = Count(); n > nStart; ) |
| { |
| m_SwpHstry.DeleteAndDestroy( --n, 1 ); |
| } |
| m_nEndDiff = 0; |
| } |
| |
| |
| sal_uInt16 SwHistory::SetTmpEnd( sal_uInt16 nNewTmpEnd ) |
| { |
| ASSERT( nNewTmpEnd <= Count(), "SwHistory::SetTmpEnd: out of bounds" ); |
| |
| sal_uInt16 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 ( sal_uInt16 n = nOld; n < nNewTmpEnd; n++ ) |
| { |
| if ( HSTRY_FLYCNT == (*this)[ n ]->Which() ) |
| { |
| static_cast<SwHistoryTxtFlyCnt*>((*this)[ n ]) |
| ->GetUDelLFmt()->RedoForRollback(); |
| } |
| } |
| |
| return nOld; |
| } |
| |
| void SwHistory::CopyFmtAttr( const SfxItemSet& rSet, sal_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( sal_True ); |
| } |
| } |
| |
| void SwHistory::CopyAttr( |
| SwpHints* pHts, |
| const sal_uLong nNodeIdx, |
| const xub_StrLen nStart, |
| const xub_StrLen nEnd, |
| const bool bCopyFields ) |
| { |
| 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( sal_uInt16 n = 0; n < pHts->Count(); n++ ) |
| { |
| pHt = pHts->GetTextHint(n); |
| nAttrStt = *pHt->GetStart(); |
| if( 0 != ( pEndIdx = pHt->GetEnd() ) && nAttrStt > nEnd ) |
| break; |
| |
| // Flys und Ftn nie kopieren !! |
| sal_Bool bNextAttr = sal_False; |
| switch( pHt->Which() ) |
| { |
| case RES_TXTATR_FIELD: |
| case RES_TXTATR_ANNOTATION: |
| case RES_TXTATR_INPUTFIELD: |
| if( !bCopyFields ) |
| bNextAttr = sal_True; |
| break; |
| case RES_TXTATR_FLYCNT: |
| case RES_TXTATR_FTN: |
| bNextAttr = sal_True; |
| break; |
| } |
| |
| if( bNextAttr ) |
| continue; |
| |
| // save all attributes that are somehow in this area |
| if ( nStart <= nAttrStt ) |
| { |
| if ( nEnd > nAttrStt ) |
| { |
| 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( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) |
| { |
| // --> OD 2010-10-05 #i114861# |
| // Do not handle a "noop" modify |
| // - e.g. <SwTxtNode::NumRuleChgd()> uses such a "noop" modify |
| // if ( m_pHistory && ( pOld || pNew ) ) |
| if ( m_pHistory && ( pOld || pNew ) && |
| 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<const 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 ); |
| sal_uInt16 nW = aIter.FirstItem()->Which(); |
| while( sal_True ) |
| { |
| m_WhichIdSet.Insert( nW ); |
| if( aIter.IsAtEnd() ) |
| break; |
| nW = aIter.NextItem()->Which(); |
| } |
| } |
| } |
| } |
| |