diff options
Diffstat (limited to 'sw/source/core/doc/docftn.cxx')
-rw-r--r-- | sw/source/core/doc/docftn.cxx | 529 |
1 files changed, 529 insertions, 0 deletions
diff --git a/sw/source/core/doc/docftn.cxx b/sw/source/core/doc/docftn.cxx new file mode 100644 index 000000000000..8d7c8523aa46 --- /dev/null +++ b/sw/source/core/doc/docftn.cxx @@ -0,0 +1,529 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 <ftnidx.hxx> +#include <rootfrm.hxx> +#include <txtftn.hxx> +#include <fmtftn.hxx> +#include <pam.hxx> +#include <pagedesc.hxx> +#include <charfmt.hxx> +#include <UndoAttribute.hxx> +#include <hints.hxx> +#include <rolbck.hxx> +#include <doc.hxx> +#include <IDocumentUndoRedo.hxx> +#include <ndtxt.hxx> +#include <poolfmt.hxx> +#include <ftninfo.hxx> + +/*********************** SwFtnInfo ***************************/ + +SwEndNoteInfo& SwEndNoteInfo::operator=(const SwEndNoteInfo& rInfo) +{ + if( rInfo.GetFtnTxtColl() ) + rInfo.GetFtnTxtColl()->Add(this); + else if ( GetRegisteredIn()) + GetRegisteredInNonConst()->Remove(this); + + if ( rInfo.aPageDescDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aPageDescDep.GetRegisteredIn())->Add( &aPageDescDep ); + else if ( aPageDescDep.GetRegisteredIn() ) + ((SwModify*)aPageDescDep.GetRegisteredIn())->Remove( &aPageDescDep ); + + if ( rInfo.aCharFmtDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aCharFmtDep.GetRegisteredIn())->Add( &aCharFmtDep ); + else if ( aCharFmtDep.GetRegisteredIn() ) + ((SwModify*)aCharFmtDep.GetRegisteredIn())->Remove( &aCharFmtDep ); + + if ( rInfo.aAnchorCharFmtDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aAnchorCharFmtDep.GetRegisteredIn())->Add( + &aAnchorCharFmtDep ); + else if( aAnchorCharFmtDep.GetRegisteredIn() ) + ((SwModify*)aAnchorCharFmtDep.GetRegisteredIn())->Remove( + &aAnchorCharFmtDep ); + + aFmt = rInfo.aFmt; + nFtnOffset = rInfo.nFtnOffset; + m_bEndNote = rInfo.m_bEndNote; + sPrefix = rInfo.sPrefix; + sSuffix = rInfo.sSuffix; + return *this; +} + + +sal_Bool SwEndNoteInfo::operator==( const SwEndNoteInfo& rInfo ) const +{ + return aPageDescDep.GetRegisteredIn() == + rInfo.aPageDescDep.GetRegisteredIn() && + aCharFmtDep.GetRegisteredIn() == + rInfo.aCharFmtDep.GetRegisteredIn() && + aAnchorCharFmtDep.GetRegisteredIn() == + rInfo.aAnchorCharFmtDep.GetRegisteredIn() && + GetFtnTxtColl() == rInfo.GetFtnTxtColl() && + aFmt.GetNumberingType() == rInfo.aFmt.GetNumberingType() && + nFtnOffset == rInfo.nFtnOffset && + m_bEndNote == rInfo.m_bEndNote && + sPrefix == rInfo.sPrefix && + sSuffix == rInfo.sSuffix; +} + + +SwEndNoteInfo::SwEndNoteInfo(const SwEndNoteInfo& rInfo) : + SwClient( rInfo.GetFtnTxtColl() ), + aPageDescDep( this, 0 ), + aCharFmtDep( this, 0 ), + aAnchorCharFmtDep( this, 0 ), + sPrefix( rInfo.sPrefix ), + sSuffix( rInfo.sSuffix ), + m_bEndNote( true ), + aFmt( rInfo.aFmt ), + nFtnOffset( rInfo.nFtnOffset ) +{ + if( rInfo.aPageDescDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aPageDescDep.GetRegisteredIn())->Add( &aPageDescDep ); + + if( rInfo.aCharFmtDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aCharFmtDep.GetRegisteredIn())->Add( &aCharFmtDep ); + + if( rInfo.aAnchorCharFmtDep.GetRegisteredIn() ) + ((SwModify*)rInfo.aAnchorCharFmtDep.GetRegisteredIn())->Add( + &aAnchorCharFmtDep ); +} + +SwEndNoteInfo::SwEndNoteInfo(SwTxtFmtColl *pFmt) : + SwClient(pFmt), + aPageDescDep( this, 0 ), + aCharFmtDep( this, 0 ), + aAnchorCharFmtDep( this, 0 ), + m_bEndNote( true ), + nFtnOffset( 0 ) +{ + aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER); +} + +SwPageDesc *SwEndNoteInfo::GetPageDesc( SwDoc &rDoc ) const +{ + if ( !aPageDescDep.GetRegisteredIn() ) + { + SwPageDesc *pDesc = rDoc.GetPageDescFromPool( static_cast<sal_uInt16>( + m_bEndNote ? RES_POOLPAGE_ENDNOTE : RES_POOLPAGE_FOOTNOTE ) ); + pDesc->Add( &((SwClient&)aPageDescDep) ); + } + + return (SwPageDesc*)( aPageDescDep.GetRegisteredIn() ); +} + +bool SwEndNoteInfo::KnowsPageDesc() const +{ + return (aPageDescDep.GetRegisteredIn() != 0); +} + +bool SwEndNoteInfo::DependsOn( const SwPageDesc* pDesc ) const +{ + return ( aPageDescDep.GetRegisteredIn() == pDesc ); +} + +void SwEndNoteInfo::ChgPageDesc( SwPageDesc *pDesc ) +{ + pDesc->Add( &((SwClient&)aPageDescDep) ); +} + +void SwEndNoteInfo::SetFtnTxtColl(SwTxtFmtColl& rFmt) +{ + rFmt.Add(this); +} + +SwCharFmt* SwEndNoteInfo::GetCharFmt(SwDoc &rDoc) const +{ + if ( !aCharFmtDep.GetRegisteredIn() ) + { + SwCharFmt* pFmt = rDoc.GetCharFmtFromPool( static_cast<sal_uInt16>( + m_bEndNote ? RES_POOLCHR_ENDNOTE : RES_POOLCHR_FOOTNOTE ) ); + pFmt->Add( &((SwClient&)aCharFmtDep) ); + } + return (SwCharFmt*)aCharFmtDep.GetRegisteredIn(); +} + +void SwEndNoteInfo::SetCharFmt( SwCharFmt* pChFmt ) +{ + DBG_ASSERT(pChFmt, "kein CharFmt?"); + pChFmt->Add( &((SwClient&)aCharFmtDep) ); +} + +SwCharFmt* SwEndNoteInfo::GetAnchorCharFmt(SwDoc &rDoc) const +{ + if( !aAnchorCharFmtDep.GetRegisteredIn() ) + { + SwCharFmt* pFmt = rDoc.GetCharFmtFromPool( static_cast<sal_uInt16>( + m_bEndNote ? RES_POOLCHR_ENDNOTE_ANCHOR : RES_POOLCHR_FOOTNOTE_ANCHOR ) ); + pFmt->Add( &((SwClient&)aAnchorCharFmtDep) ); + } + return (SwCharFmt*)aAnchorCharFmtDep.GetRegisteredIn(); +} + +void SwEndNoteInfo::SetAnchorCharFmt( SwCharFmt* pChFmt ) +{ + DBG_ASSERT(pChFmt, "kein CharFmt?"); + pChFmt->Add( &((SwClient&)aAnchorCharFmtDep) ); +} + +void SwEndNoteInfo::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) +{ + sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ; + + if( RES_ATTRSET_CHG == nWhich || + RES_FMT_CHG == nWhich ) + { + SwDoc* pDoc; + if( aCharFmtDep.GetRegisteredIn() ) + pDoc = ((SwCharFmt*)aCharFmtDep.GetRegisteredIn())->GetDoc(); + else + pDoc = ((SwCharFmt*)aAnchorCharFmtDep.GetRegisteredIn())->GetDoc(); + SwFtnIdxs& rFtnIdxs = pDoc->GetFtnIdxs(); + for( sal_uInt16 nPos = 0; nPos < rFtnIdxs.Count(); ++nPos ) + { + SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if ( rFtn.IsEndNote() == m_bEndNote ) + { + pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr()); + } + } + } + else + CheckRegistration( pOld, pNew ); +} + +SwFtnInfo& SwFtnInfo::operator=(const SwFtnInfo& rInfo) +{ + SwEndNoteInfo::operator=(rInfo); + aQuoVadis = rInfo.aQuoVadis; + aErgoSum = rInfo.aErgoSum; + ePos = rInfo.ePos; + eNum = rInfo.eNum; + return *this; +} + + +sal_Bool SwFtnInfo::operator==( const SwFtnInfo& rInfo ) const +{ + return ePos == rInfo.ePos && + eNum == rInfo.eNum && + SwEndNoteInfo::operator==(rInfo) && + aQuoVadis == rInfo.aQuoVadis && + aErgoSum == rInfo.aErgoSum; +} + + +SwFtnInfo::SwFtnInfo(const SwFtnInfo& rInfo) : + SwEndNoteInfo( rInfo ), + aQuoVadis( rInfo.aQuoVadis ), + aErgoSum( rInfo.aErgoSum ), + ePos( rInfo.ePos ), + eNum( rInfo.eNum ) +{ + m_bEndNote = false; +} + +SwFtnInfo::SwFtnInfo(SwTxtFmtColl *pFmt) : + SwEndNoteInfo( pFmt ), + ePos( FTNPOS_PAGE ), + eNum( FTNNUM_DOC ) +{ + aFmt.SetNumberingType(SVX_NUM_ARABIC); + m_bEndNote = false; +} + +/*********************** SwDoc ***************************/ + + +void SwDoc::SetFtnInfo(const SwFtnInfo& rInfo) +{ + SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219 + if( !(GetFtnInfo() == rInfo) ) + { + const SwFtnInfo &rOld = GetFtnInfo(); + + if (GetIDocumentUndoRedo().DoesUndo()) + { + GetIDocumentUndoRedo().AppendUndo( new SwUndoFootNoteInfo(rOld) ); + } + + sal_Bool bFtnPos = rInfo.ePos != rOld.ePos; + sal_Bool bFtnDesc = rOld.ePos == FTNPOS_CHAPTER && + rInfo.GetPageDesc( *this ) != rOld.GetPageDesc( *this ); + sal_Bool bExtra = rInfo.aQuoVadis != rOld.aQuoVadis || + rInfo.aErgoSum != rOld.aErgoSum || + rInfo.aFmt.GetNumberingType() != rOld.aFmt.GetNumberingType() || + rInfo.GetPrefix() != rOld.GetPrefix() || + rInfo.GetSuffix() != rOld.GetSuffix(); + SwCharFmt *pOldChrFmt = rOld.GetCharFmt( *this ), + *pNewChrFmt = rInfo.GetCharFmt( *this ); + sal_Bool bFtnChrFmts = pOldChrFmt != pNewChrFmt; + + *pFtnInfo = rInfo; + + if (pTmpRoot) + { + std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080304 + if ( bFtnPos ) + //pTmpRoot->RemoveFtns(); + std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllRemoveFtns));//swmod 080305 + else + { + //pTmpRoot->UpdateFtnNums(); + std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::UpdateFtnNums));//swmod 080304 + if ( bFtnDesc ) + //pTmpRoot->CheckFtnPageDescs( FALSE ); + std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs), sal_False));//swmod 080304 + if ( bExtra ) + { + //Fuer die Benachrichtung bezueglich ErgoSum usw. sparen wir uns + //extra-Code und nutzen die vorhandenen Wege. + SwFtnIdxs& rFtnIdxs = GetFtnIdxs(); + for( sal_uInt16 nPos = 0; nPos < rFtnIdxs.Count(); ++nPos ) + { + SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if ( !rFtn.IsEndNote() ) + pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr()); + } + } + } + } //swmod 080219 + if( FTNNUM_PAGE != rInfo.eNum ) + GetFtnIdxs().UpdateAllFtn(); + else if( bFtnChrFmts ) + { + SwFmtChg aOld( pOldChrFmt ); + SwFmtChg aNew( pNewChrFmt ); + pFtnInfo->ModifyNotification( &aOld, &aNew ); + } + + // #i81002# no update during loading + if ( !IsInReading() ) + { + UpdateRefFlds(NULL); + } + SetModified(); + } +} + +void SwDoc::SetEndNoteInfo(const SwEndNoteInfo& rInfo) +{ + SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219 + if( !(GetEndNoteInfo() == rInfo) ) + { + if(GetIDocumentUndoRedo().DoesUndo()) + { + SwUndo *const pUndo( new SwUndoEndNoteInfo( GetEndNoteInfo() ) ); + GetIDocumentUndoRedo().AppendUndo(pUndo); + } + + sal_Bool bNumChg = rInfo.nFtnOffset != GetEndNoteInfo().nFtnOffset; + // this seems to be an optimization: UpdateAllFtn() is only called + // if the offset changes; if the offset is the same, + // but type/prefix/suffix changes, just set new numbers. + bool const bExtra = !bNumChg && + ( (rInfo.aFmt.GetNumberingType() != + GetEndNoteInfo().aFmt.GetNumberingType()) + || (rInfo.GetPrefix() != GetEndNoteInfo().GetPrefix()) + || (rInfo.GetSuffix() != GetEndNoteInfo().GetSuffix()) + ); + sal_Bool bFtnDesc = rInfo.GetPageDesc( *this ) != + GetEndNoteInfo().GetPageDesc( *this ); + SwCharFmt *pOldChrFmt = GetEndNoteInfo().GetCharFmt( *this ), + *pNewChrFmt = rInfo.GetCharFmt( *this ); + sal_Bool bFtnChrFmts = pOldChrFmt != pNewChrFmt; + + *pEndNoteInfo = rInfo; + + if ( pTmpRoot ) + { + if ( bFtnDesc ) + //pTmpRoot->CheckFtnPageDescs( TRUE ); + { + std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); + std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs), sal_True));//swmod 080304 + } + if ( bExtra ) + { + //Fuer die Benachrichtung bezueglich ErgoSum usw. sparen wir uns + //extra-Code und nutzen die vorhandenen Wege. + SwFtnIdxs& rFtnIdxs = GetFtnIdxs(); + for( sal_uInt16 nPos = 0; nPos < rFtnIdxs.Count(); ++nPos ) + { + SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ]; + const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); + if ( rFtn.IsEndNote() ) + pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr()); + } + } + } //swmod 080219 + if( bNumChg ) + GetFtnIdxs().UpdateAllFtn(); + else if( bFtnChrFmts ) + { + SwFmtChg aOld( pOldChrFmt ); + SwFmtChg aNew( pNewChrFmt ); + pEndNoteInfo->ModifyNotification( &aOld, &aNew ); + } + + // #i81002# no update during loading + if ( !IsInReading() ) + { + UpdateRefFlds(NULL); + } + SetModified(); + } +} + + +bool SwDoc::SetCurFtn( const SwPaM& rPam, const String& rNumStr, + sal_uInt16 nNumber, bool bIsEndNote ) +{ + SwFtnIdxs& rFtnArr = GetFtnIdxs(); + SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219 + + const SwPosition* pStt = rPam.Start(), *pEnd = rPam.End(); + const sal_uLong nSttNd = pStt->nNode.GetIndex(); + const xub_StrLen nSttCnt = pStt->nContent.GetIndex(); + const sal_uLong nEndNd = pEnd->nNode.GetIndex(); + const xub_StrLen nEndCnt = pEnd->nContent.GetIndex(); + + sal_uInt16 nPos; + rFtnArr.SeekEntry( pStt->nNode, &nPos ); + + SwUndoChangeFootNote* pUndo = 0; + if (GetIDocumentUndoRedo().DoesUndo()) + { + GetIDocumentUndoRedo().ClearRedo(); // AppendUndo far below, so leave it + pUndo = new SwUndoChangeFootNote( rPam, rNumStr, nNumber, bIsEndNote ); + } + + SwTxtFtn* pTxtFtn; + sal_uLong nIdx; + sal_Bool bChg = sal_False; + sal_Bool bTypeChgd = sal_False; + sal_uInt16 n = nPos; // sichern + while( nPos < rFtnArr.Count() && + (( nIdx = _SwTxtFtn_GetIndex((pTxtFtn = rFtnArr[ nPos++ ] ))) + < nEndNd || ( nIdx == nEndNd && + nEndCnt >= *pTxtFtn->GetStart() )) ) + if( nIdx > nSttNd || ( nIdx == nSttNd && + nSttCnt <= *pTxtFtn->GetStart() ) ) + { + const SwFmtFtn& rFtn = pTxtFtn->GetFtn(); + if( rFtn.GetNumStr() != rNumStr || + rFtn.IsEndNote() != bIsEndNote ) + { + bChg = sal_True; + if ( pUndo ) + { + pUndo->GetHistory().Add( *pTxtFtn ); + } + + pTxtFtn->SetNumber( nNumber, &rNumStr ); + if( rFtn.IsEndNote() != bIsEndNote ) + { + ((SwFmtFtn&)rFtn).SetEndNote( bIsEndNote ); + bTypeChgd = sal_True; + pTxtFtn->CheckCondColl(); + //#i11339# dispose UNO wrapper when a footnote is changed to an endnote or vice versa + SwPtrMsgPoolItem aMsgHint( RES_FOOTNOTE_DELETED, (void*)&pTxtFtn->GetAttr() ); + GetUnoCallBack()->ModifyNotification( &aMsgHint, &aMsgHint ); + } + } + } + + nPos = n; // nach vorne gibt es auch noch welche ! + while( nPos && + (( nIdx = _SwTxtFtn_GetIndex((pTxtFtn = rFtnArr[ --nPos ] ))) + > nSttNd || ( nIdx == nSttNd && + nSttCnt <= *pTxtFtn->GetStart() )) ) + if( nIdx < nEndNd || ( nIdx == nEndNd && + nEndCnt >= *pTxtFtn->GetStart() ) ) + { + const SwFmtFtn& rFtn = pTxtFtn->GetFtn(); + if( rFtn.GetNumStr() != rNumStr || + rFtn.IsEndNote() != bIsEndNote ) + { + bChg = sal_True; + if ( pUndo ) + { + pUndo->GetHistory().Add( *pTxtFtn ); + } + + pTxtFtn->SetNumber( nNumber, &rNumStr ); + if( rFtn.IsEndNote() != bIsEndNote ) + { + ((SwFmtFtn&)rFtn).SetEndNote( bIsEndNote ); + bTypeChgd = sal_True; + pTxtFtn->CheckCondColl(); + } + } + } + + // wer muss angestossen werden ?? + if( bChg ) + { + if( pUndo ) + { + GetIDocumentUndoRedo().AppendUndo(pUndo); + } + + if ( bTypeChgd ) + rFtnArr.UpdateAllFtn(); + if( FTNNUM_PAGE != GetFtnInfo().eNum ) + { + if ( !bTypeChgd ) + rFtnArr.UpdateAllFtn(); + } + else if( pTmpRoot ) + // + { + std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); + std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::UpdateFtnNums)); + } //swmod 080304pTmpRoot->UpdateFtnNums(); //swmod 080219 + SetModified(); + } + else + delete pUndo; + return bChg; +} + + + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |