diff options
author | Bjoern Michaelsen <bjoern.michaelsen@canonical.com> | 2014-07-25 00:39:54 +0200 |
---|---|---|
committer | Bjoern Michaelsen <bjoern.michaelsen@canonical.com> | 2014-07-25 09:47:53 +0200 |
commit | fec5892741df952ebf97ea745fce3d061c75de34 (patch) | |
tree | 323f9daa61408376f9a01fdbf0b8da29dafa9790 /sw | |
parent | 6c1f2ea2aa11b2c8fd42b455c7c452194ed2c1e7 (diff) |
move CntntIdxStore to own file
Change-Id: Ic8280478b154b9b132f74e260edea46911cb1803
Diffstat (limited to 'sw')
-rw-r--r-- | sw/Library_sw.mk | 1 | ||||
-rw-r--r-- | sw/source/core/doc/CntntIdxStore.cxx | 455 | ||||
-rw-r--r-- | sw/source/core/doc/docbm.cxx | 400 |
3 files changed, 456 insertions, 400 deletions
diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index 0366a642c72b..75f26b296a67 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -159,6 +159,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\ sw/source/core/crsr/overlayrangesoutline \ sw/source/core/doc/SwStyleNameMapper \ sw/source/core/doc/acmplwrd \ + sw/source/core/doc/CntntIdxStore \ sw/source/core/doc/dbgoutsw \ sw/source/core/doc/doc \ sw/source/core/doc/docbasic \ diff --git a/sw/source/core/doc/CntntIdxStore.cxx b/sw/source/core/doc/CntntIdxStore.cxx new file mode 100644 index 000000000000..7b7ba3e364cd --- /dev/null +++ b/sw/source/core/doc/CntntIdxStore.cxx @@ -0,0 +1,455 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <MarkManager.hxx> +#include <bookmrk.hxx> +#include <boost/bind.hpp> +#include <boost/foreach.hpp> +#include <boost/function.hpp> +#include <cntfrm.hxx> +#include <crossrefbookmark.hxx> +#include <annotationmark.hxx> +#include <dcontact.hxx> +#include <doc.hxx> +#include <docary.hxx> +#include <xmloff/odffields.hxx> +#include <editsh.hxx> +#include <fmtanchr.hxx> +#include <frmfmt.hxx> +#include <functional> +#include <hintids.hxx> +#include <mvsave.hxx> +#include <ndtxt.hxx> +#include <node.hxx> +#include <pam.hxx> +#include <redline.hxx> +#include <rolbck.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <sortedobjs.hxx> +#include <sfx2/linkmgr.hxx> +#include <swserv.hxx> +#include <swundo.hxx> +#include <unocrsr.hxx> +#include <viscrs.hxx> +#include <edimp.hxx> +#include <stdio.h> + +using namespace ::boost; +using namespace ::sw::mark; + +namespace +{ + // #i59534: If a paragraph will be splitted we have to restore some redline positions + // This help function checks a position compared with a node and an content index + + static const int BEFORE_NODE = 0; // Position before the given node index + static const int BEFORE_SAME_NODE = 1; // Same node index but content index before given content index + static const int SAME_POSITION = 2; // Same node index and samecontent index + static const int BEHIND_SAME_NODE = 3; // Same node index but content index behind given content index + static const int BEHIND_NODE = 4; // Position behind the given node index + + static int lcl_RelativePosition( const SwPosition& rPos, sal_uLong nNode, sal_Int32 nCntnt ) + { + sal_uLong nIndex = rPos.nNode.GetIndex(); + int nReturn = BEFORE_NODE; + if( nIndex == nNode ) + { + const sal_Int32 nCntIdx = rPos.nContent.GetIndex(); + if( nCntIdx < nCntnt ) + nReturn = BEFORE_SAME_NODE; + else if( nCntIdx == nCntnt ) + nReturn = SAME_POSITION; + else + nReturn = BEHIND_SAME_NODE; + } + else if( nIndex > nNode ) + nReturn = BEHIND_NODE; + return nReturn; + } + struct MarkEntry + { + long int m_nIdx; + bool m_bOther; + sal_Int32 m_nCntnt; +#if 0 + void Dump() + { + SAL_INFO("sw.core", "Index: " << m_nIdx << "\tOther: " << m_bOther << "\tContent: " << m_nCntnt); + } +#endif + }; + struct PaMEntry + { + SwPaM* m_pPaM; + bool m_isMark; + sal_Int32 m_nCntnt; + }; + struct OffsetUpdater + { + const SwCntntNode* m_pNewCntntNode; + const sal_Int32 m_nOffset; + OffsetUpdater(SwCntntNode* pNewCntntNode, sal_Int32 nOffset) + : m_pNewCntntNode(pNewCntntNode), m_nOffset(nOffset) {}; + void operator()(SwPosition& rPos, sal_Int32 nCntnt) const + { + rPos.nNode = *m_pNewCntntNode; + rPos.nContent.Assign(const_cast<SwCntntNode*>(m_pNewCntntNode), nCntnt + m_nOffset); + }; + }; + struct LimitUpdater + { + const SwCntntNode* m_pNewCntntNode; + const sal_uLong m_nLen; + const sal_Int32 m_nCorrLen; + LimitUpdater(SwCntntNode* pNewCntntNode, sal_uLong nLen, sal_Int32 nCorrLen) + : m_pNewCntntNode(pNewCntntNode), m_nLen(nLen), m_nCorrLen(nCorrLen) {}; + void operator()(SwPosition& rPos, sal_Int32 nCntnt) const + { + if( nCntnt < m_nCorrLen ) + { + rPos.nNode = *m_pNewCntntNode; + rPos.nContent.Assign(const_cast<SwCntntNode*>(m_pNewCntntNode), std::min( nCntnt, static_cast<sal_Int32>(m_nLen) ) ); + } + else + { + rPos.nNode = *m_pNewCntntNode; + rPos.nContent -= m_nCorrLen; + } + }; + }; + struct CntntIdxStoreImpl : sw::mark::CntntIdxStore + { + std::vector<MarkEntry> m_aBkmkEntries; + std::vector<MarkEntry> m_aRedlineEntries; + std::vector<MarkEntry> m_aFlyEntries; + std::vector<PaMEntry> m_aUnoCrsrEntries; + std::vector<PaMEntry> m_aShellCrsrEntries; + typedef boost::function<void (SwPosition& rPos, sal_Int32 nCntnt)> updater_t; + virtual void Clear() SAL_OVERRIDE + { + m_aBkmkEntries.clear(); + m_aRedlineEntries.clear(); + m_aFlyEntries.clear(); + m_aUnoCrsrEntries.clear(); + m_aShellCrsrEntries.clear(); + } + virtual bool Empty() SAL_OVERRIDE + { + return m_aBkmkEntries.empty() && m_aRedlineEntries.empty() && m_aFlyEntries.empty() && m_aUnoCrsrEntries.empty() && m_aShellCrsrEntries.empty(); + } + virtual void Save(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt, sal_uInt8 nSaveFly=0) SAL_OVERRIDE + { + SaveBkmks(pDoc, nNode, nCntnt); + SaveRedlines(pDoc, nNode, nCntnt); + SaveFlys(pDoc, nNode, nCntnt, nSaveFly); + SaveUnoCrsrs(pDoc, nNode, nCntnt); + SaveShellCrsrs(pDoc, nNode, nCntnt); + } + virtual void Restore(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nOffset=0, bool bAuto = false) SAL_OVERRIDE + { + SwCntntNode* pCNd = pDoc->GetNodes()[ nNode ]->GetCntntNode(); + updater_t aUpdater = OffsetUpdater(pCNd, nOffset); + RestoreBkmks(pDoc, aUpdater); + RestoreRedlines(pDoc, aUpdater); + RestoreFlys(pDoc, aUpdater, bAuto); + RestoreUnoCrsrs(pDoc, aUpdater); + RestoreShellCrsrs(pDoc, aUpdater); + } + virtual void Restore(SwNode& rNd, sal_Int32 nLen, sal_Int32 nCorrLen) SAL_OVERRIDE + { + SwCntntNode* pCNd = (SwCntntNode*)rNd.GetCntntNode(); + SwDoc* pDoc = rNd.GetDoc(); + updater_t aUpdater = LimitUpdater(pCNd, nLen, nCorrLen); + RestoreBkmks(pDoc, aUpdater); + RestoreRedlines(pDoc, aUpdater); + RestoreFlys(pDoc, aUpdater, false); + RestoreUnoCrsrs(pDoc, aUpdater); + RestoreShellCrsrs(pDoc, aUpdater); + } + virtual ~CntntIdxStoreImpl(){}; + private: + inline void SaveBkmks(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt); + inline void RestoreBkmks(SwDoc* pDoc, updater_t& rUpdater); + inline void SaveRedlines(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt); + inline void RestoreRedlines(SwDoc* pDoc, updater_t& rUpdater); + inline void SaveFlys(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt, sal_uInt8 nSaveFly); + inline void RestoreFlys(SwDoc* pDoc, updater_t& rUpdater, bool bAuto); + inline void SaveUnoCrsrs(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt); + inline void RestoreUnoCrsrs(SwDoc* pDoc, updater_t& rUpdater); + inline void SaveShellCrsrs(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt); + inline void RestoreShellCrsrs(SwDoc* pDoc, updater_t& rUpdater); + inline const SwPosition& GetRightMarkPos(::sw::mark::IMark* pMark, bool bOther) + { return bOther ? pMark->GetOtherMarkPos() : pMark->GetMarkPos(); }; + inline void SetRightMarkPos(MarkBase* pMark, bool bOther, const SwPosition* const pPos) + { bOther ? pMark->SetOtherMarkPos(*pPos) : pMark->SetMarkPos(*pPos); }; + }; + static inline void lcl_ChkPaM( std::vector<PaMEntry>& rPaMEntries, const sal_uLong nNode, const sal_Int32 nCntnt, SwPaM& rPaM, const bool bPoint) + { + const SwPosition* pPos = &rPaM.GetBound( bPoint ); + if( pPos->nNode.GetIndex() == nNode && pPos->nContent.GetIndex() < nCntnt ) + { + const PaMEntry aEntry = { &rPaM, bPoint, pPos->nContent.GetIndex() }; + rPaMEntries.push_back(aEntry); + } + } + static inline void lcl_ChkPaMBoth( std::vector<PaMEntry>& rPaMEntries, const sal_uLong nNode, const sal_Int32 nCntnt, SwPaM& rPaM) + { + lcl_ChkPaM(rPaMEntries, nNode, nCntnt, rPaM, true); + lcl_ChkPaM(rPaMEntries, nNode, nCntnt, rPaM, false); + } + +#if 0 + static void DumpEntries(std::vector<MarkEntry>* pEntries) + { + BOOST_FOREACH(MarkEntry& aEntry, *pEntries) + aEntry.Dump(); + } +#endif +} + +void CntntIdxStoreImpl::SaveBkmks(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt) +{ + IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess(); + const IDocumentMarkAccess::const_iterator_t ppBkmkEnd = pMarkAccess->getAllMarksEnd(); + for( + IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->getAllMarksBegin(); + ppBkmk != ppBkmkEnd; + ++ppBkmk) + { + const ::sw::mark::IMark* pBkmk = ppBkmk->get(); + bool bMarkPosEqual = false; + if(pBkmk->GetMarkPos().nNode.GetIndex() == nNode + && pBkmk->GetMarkPos().nContent.GetIndex() <= nCntnt) + { + if(pBkmk->GetMarkPos().nContent.GetIndex() < nCntnt) + { + const MarkEntry aEntry = { ppBkmk - pMarkAccess->getAllMarksBegin(), false, pBkmk->GetMarkPos().nContent.GetIndex() }; + m_aBkmkEntries.push_back(aEntry); + } + else // if a bookmark position is equal nCntnt, the other position + bMarkPosEqual = true; // has to decide if it is added to the array + } + if(pBkmk->IsExpanded() + && pBkmk->GetOtherMarkPos().nNode.GetIndex() == nNode + && pBkmk->GetOtherMarkPos().nContent.GetIndex() <= nCntnt) + { + if(bMarkPosEqual) + { // the other position is before, the (main) position is equal + const MarkEntry aEntry = { ppBkmk - pMarkAccess->getAllMarksBegin(), false, pBkmk->GetMarkPos().nContent.GetIndex() }; + m_aBkmkEntries.push_back(aEntry); + } + const MarkEntry aEntry = { ppBkmk - pMarkAccess->getAllMarksBegin(), true, pBkmk->GetOtherMarkPos().nContent.GetIndex() }; + m_aBkmkEntries.push_back(aEntry); + } + } +} + +void CntntIdxStoreImpl::RestoreBkmks(SwDoc* pDoc, updater_t& rUpdater) +{ + IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess(); + BOOST_FOREACH(const MarkEntry& aEntry, m_aBkmkEntries) + { + if (MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getAllMarksBegin()[aEntry.m_nIdx].get())) + { + SwPosition aNewPos(GetRightMarkPos(pMark, aEntry.m_bOther)); + rUpdater(aNewPos, aEntry.m_nCntnt); + SetRightMarkPos(pMark, aEntry.m_bOther, &aNewPos); + } + } +} + +void CntntIdxStoreImpl::SaveRedlines(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt) +{ + const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl(); + for( long int nIdx = 0 ; static_cast<unsigned long int>(nIdx) < rRedlTbl.size(); ++nIdx ) + { + const SwRangeRedline* pRdl = rRedlTbl[ nIdx ]; + int nPointPos = lcl_RelativePosition( *pRdl->GetPoint(), nNode, nCntnt ); + int nMarkPos = pRdl->HasMark() ? lcl_RelativePosition( *pRdl->GetMark(), nNode, nCntnt ) : + nPointPos; + // #i59534: We have to store the positions inside the same node before the insert position + // and the one at the insert position if the corresponding Point/Mark position is before + // the insert position. + if( nPointPos == BEFORE_SAME_NODE || + ( nPointPos == SAME_POSITION && nMarkPos < SAME_POSITION ) ) + { + const MarkEntry aEntry = { nIdx, false, pRdl->GetPoint()->nContent.GetIndex() }; + m_aRedlineEntries.push_back(aEntry); + } + if( pRdl->HasMark() && ( nMarkPos == BEFORE_SAME_NODE || + ( nMarkPos == SAME_POSITION && nPointPos < SAME_POSITION ) ) ) + { + const MarkEntry aEntry = { nIdx, true, pRdl->GetMark()->nContent.GetIndex() }; + m_aRedlineEntries.push_back(aEntry); + } + } +} + +void CntntIdxStoreImpl::RestoreRedlines(SwDoc* pDoc, updater_t& rUpdater) +{ + const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl(); + SwPosition* pPos = NULL; + BOOST_FOREACH(const MarkEntry& aEntry, m_aRedlineEntries) + { + pPos = (SwPosition*)( aEntry.m_bOther + ? rRedlTbl[ aEntry.m_nIdx ]->GetMark() + : rRedlTbl[ aEntry.m_nIdx ]->GetPoint()); + rUpdater(*pPos, aEntry.m_nCntnt); + } +} + +void CntntIdxStoreImpl::SaveFlys(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt, sal_uInt8 nSaveFly) +{ + SwCntntNode *pNode = pDoc->GetNodes()[nNode]->GetCntntNode(); + if( !pNode ) + return; + SwFrm* pFrm = pNode->getLayoutFrm( pDoc->GetCurrentLayout() ); + if( pFrm ) + { + if( !pFrm->GetDrawObjs() ) + return; // if we have a layout and no DrawObjs, we can skip this + } + MarkEntry aSave; + BOOST_FOREACH(const SwFrmFmt* pFrmFmt, *pDoc->GetSpzFrmFmts()) + { + if ( RES_FLYFRMFMT == pFrmFmt->Which() || RES_DRAWFRMFMT == pFrmFmt->Which() ) + { + bool bSkip = false; + const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); + SwPosition const*const pAPos = rAnchor.GetCntntAnchor(); + if ( pAPos && ( nNode == pAPos->nNode.GetIndex() ) && + ( FLY_AT_PARA == rAnchor.GetAnchorId() || + FLY_AT_CHAR == rAnchor.GetAnchorId() ) ) + { + aSave.m_bOther = false; + aSave.m_nCntnt = pAPos->nContent.GetIndex(); + if ( FLY_AT_CHAR == rAnchor.GetAnchorId() ) + { + if( nCntnt <= aSave.m_nCntnt ) + { + if( SAVEFLY_SPLIT == nSaveFly ) + aSave.m_bOther = true; + else + bSkip = true; + } + } + if(!bSkip) + m_aFlyEntries.push_back(aSave); + } + } + ++aSave.m_nIdx; + } +} + +void CntntIdxStoreImpl::RestoreFlys(SwDoc* pDoc, updater_t& rUpdater, bool bAuto) +{ + SwFrmFmts* pSpz = pDoc->GetSpzFrmFmts(); + BOOST_FOREACH(const MarkEntry& aEntry, m_aFlyEntries) + { + if(!aEntry.m_bOther) + { + SwFrmFmt *pFrmFmt = (*pSpz)[ aEntry.m_nIdx ]; + const SwFmtAnchor& rFlyAnchor = pFrmFmt->GetAnchor(); + if( rFlyAnchor.GetCntntAnchor() ) + { + SwFmtAnchor aNew( rFlyAnchor ); + SwPosition aNewPos( *rFlyAnchor.GetCntntAnchor() ); + rUpdater(aNewPos, aEntry.m_nCntnt); + if ( FLY_AT_CHAR != rFlyAnchor.GetAnchorId() ) + { + aNewPos.nContent.Assign( 0, 0 ); + } + aNew.SetAnchor( &aNewPos ); + pFrmFmt->SetFmtAttr( aNew ); + } + } + else if( bAuto ) + { + SwFrmFmt *pFrmFmt = (*pSpz)[ aEntry.m_nIdx ]; + SfxPoolItem *pAnchor = (SfxPoolItem*)&pFrmFmt->GetAnchor(); + pFrmFmt->NotifyClients( pAnchor, pAnchor ); + } + } +} + +void CntntIdxStoreImpl::SaveUnoCrsrs(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt) +{ + BOOST_FOREACH(const SwUnoCrsr* pUnoCrsr, pDoc->GetUnoCrsrTbl()) + { + FOREACHPAM_START( const_cast<SwUnoCrsr*>(pUnoCrsr) ) + lcl_ChkPaMBoth( m_aUnoCrsrEntries, nNode, nCntnt, *PCURCRSR ); + FOREACHPAM_END() + const SwUnoTableCrsr* pUnoTblCrsr = dynamic_cast<const SwUnoTableCrsr*>(pUnoCrsr); + if( pUnoTblCrsr ) + { + FOREACHPAM_START( &(const_cast<SwUnoTableCrsr*>(pUnoTblCrsr))->GetSelRing() ) + lcl_ChkPaMBoth( m_aUnoCrsrEntries, nNode, nCntnt, *PCURCRSR ); + FOREACHPAM_END() + } + } +} + +void CntntIdxStoreImpl::RestoreUnoCrsrs(SwDoc* /* pDoc */, updater_t& rUpdater) +{ + BOOST_FOREACH(const PaMEntry& aEntry, m_aUnoCrsrEntries) + { + rUpdater(aEntry.m_pPaM->GetBound(!aEntry.m_isMark), aEntry.m_nCntnt); + } +} + +void CntntIdxStoreImpl::SaveShellCrsrs(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt) +{ + SwCrsrShell* pShell = pDoc->GetEditShell(); + if( !pShell ) + return; + SwViewShell *_pStartShell = pShell; + do { + if( _pStartShell->IsA( TYPE( SwCrsrShell )) ) + { + SwPaM *_pStkCrsr = ((SwCrsrShell*)_pStartShell)->GetStkCrsr(); + if( _pStkCrsr ) + do { + lcl_ChkPaMBoth( m_aShellCrsrEntries, nNode, nCntnt, *_pStkCrsr); + } while ( (_pStkCrsr != 0 ) && + ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != ((SwCrsrShell*)_pStartShell)->GetStkCrsr()) ); + + FOREACHPAM_START( ((SwCrsrShell*)_pStartShell)->_GetCrsr() ) + lcl_ChkPaMBoth( m_aShellCrsrEntries, nNode, nCntnt, *PCURCRSR); + FOREACHPAM_END() + } + } while((_pStartShell=(SwViewShell*)_pStartShell->GetNext())!= pShell ); +} + +void CntntIdxStoreImpl::RestoreShellCrsrs(SwDoc* /* pDoc */, updater_t& rUpdater) +{ + BOOST_FOREACH(const PaMEntry& aEntry, m_aShellCrsrEntries) + { + rUpdater(aEntry.m_pPaM->GetBound(aEntry.m_isMark), aEntry.m_nCntnt); + } +} + +namespace sw { namespace mark { + boost::shared_ptr<CntntIdxStore> CntntIdxStore::Create() + { + return boost::shared_ptr<CntntIdxStore>(new CntntIdxStoreImpl()); + } +}} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx index 4fe709041be9..db2358c76c6f 100644 --- a/sw/source/core/doc/docbm.cxx +++ b/sw/source/core/doc/docbm.cxx @@ -1113,34 +1113,6 @@ namespace sw { namespace mark namespace { - // #i59534: If a paragraph will be splitted we have to restore some redline positions - // This help function checks a position compared with a node and an content index - - static const int BEFORE_NODE = 0; // Position before the given node index - static const int BEFORE_SAME_NODE = 1; // Same node index but content index before given content index - static const int SAME_POSITION = 2; // Same node index and samecontent index - static const int BEHIND_SAME_NODE = 3; // Same node index but content index behind given content index - static const int BEHIND_NODE = 4; // Position behind the given node index - - static int lcl_RelativePosition( const SwPosition& rPos, sal_uLong nNode, sal_Int32 nCntnt ) - { - sal_uLong nIndex = rPos.nNode.GetIndex(); - int nReturn = BEFORE_NODE; - if( nIndex == nNode ) - { - const sal_Int32 nCntIdx = rPos.nContent.GetIndex(); - if( nCntIdx < nCntnt ) - nReturn = BEFORE_SAME_NODE; - else if( nCntIdx == nCntnt ) - nReturn = SAME_POSITION; - else - nReturn = BEHIND_SAME_NODE; - } - else if( nIndex > nNode ) - nReturn = BEHIND_NODE; - return nReturn; - } - static inline bool lcl_Greater( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx ) { return rPos.nNode > rNdIdx || ( pIdx && rPos.nNode == rNdIdx && rPos.nContent > pIdx->GetIndex() ); @@ -1354,376 +1326,4 @@ void _DelBookmarks( } } - - -namespace -{ - struct MarkEntry - { - long int m_nIdx; - bool m_bOther; - sal_Int32 m_nCntnt; -#if 0 - void Dump() - { - SAL_INFO("sw.core", "Index: " << m_nIdx << "\tOther: " << m_bOther << "\tContent: " << m_nCntnt); - } -#endif - }; - struct PaMEntry - { - SwPaM* m_pPaM; - bool m_isMark; - sal_Int32 m_nCntnt; - }; - struct OffsetUpdater - { - const SwCntntNode* m_pNewCntntNode; - const sal_Int32 m_nOffset; - OffsetUpdater(SwCntntNode* pNewCntntNode, sal_Int32 nOffset) - : m_pNewCntntNode(pNewCntntNode), m_nOffset(nOffset) {}; - void operator()(SwPosition& rPos, sal_Int32 nCntnt) const - { - rPos.nNode = *m_pNewCntntNode; - rPos.nContent.Assign(const_cast<SwCntntNode*>(m_pNewCntntNode), nCntnt + m_nOffset); - }; - }; - struct LimitUpdater - { - const SwCntntNode* m_pNewCntntNode; - const sal_uLong m_nLen; - const sal_Int32 m_nCorrLen; - LimitUpdater(SwCntntNode* pNewCntntNode, sal_uLong nLen, sal_Int32 nCorrLen) - : m_pNewCntntNode(pNewCntntNode), m_nLen(nLen), m_nCorrLen(nCorrLen) {}; - void operator()(SwPosition& rPos, sal_Int32 nCntnt) const - { - if( nCntnt < m_nCorrLen ) - { - rPos.nNode = *m_pNewCntntNode; - rPos.nContent.Assign(const_cast<SwCntntNode*>(m_pNewCntntNode), std::min( nCntnt, static_cast<sal_Int32>(m_nLen) ) ); - } - else - { - rPos.nNode = *m_pNewCntntNode; - rPos.nContent -= m_nCorrLen; - } - }; - }; - struct CntntIdxStoreImpl : sw::mark::CntntIdxStore - { - std::vector<MarkEntry> m_aBkmkEntries; - std::vector<MarkEntry> m_aRedlineEntries; - std::vector<MarkEntry> m_aFlyEntries; - std::vector<PaMEntry> m_aUnoCrsrEntries; - std::vector<PaMEntry> m_aShellCrsrEntries; - typedef boost::function<void (SwPosition& rPos, sal_Int32 nCntnt)> updater_t; - virtual void Clear() SAL_OVERRIDE - { - m_aBkmkEntries.clear(); - m_aRedlineEntries.clear(); - m_aFlyEntries.clear(); - m_aUnoCrsrEntries.clear(); - m_aShellCrsrEntries.clear(); - } - virtual bool Empty() SAL_OVERRIDE - { - return m_aBkmkEntries.empty() && m_aRedlineEntries.empty() && m_aFlyEntries.empty() && m_aUnoCrsrEntries.empty() && m_aShellCrsrEntries.empty(); - } - virtual void Save(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt, sal_uInt8 nSaveFly=0) SAL_OVERRIDE - { - SaveBkmks(pDoc, nNode, nCntnt); - SaveRedlines(pDoc, nNode, nCntnt); - SaveFlys(pDoc, nNode, nCntnt, nSaveFly); - SaveUnoCrsrs(pDoc, nNode, nCntnt); - SaveShellCrsrs(pDoc, nNode, nCntnt); - } - virtual void Restore(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nOffset=0, bool bAuto = false) SAL_OVERRIDE - { - SwCntntNode* pCNd = pDoc->GetNodes()[ nNode ]->GetCntntNode(); - updater_t aUpdater = OffsetUpdater(pCNd, nOffset); - RestoreBkmks(pDoc, aUpdater); - RestoreRedlines(pDoc, aUpdater); - RestoreFlys(pDoc, aUpdater, bAuto); - RestoreUnoCrsrs(pDoc, aUpdater); - RestoreShellCrsrs(pDoc, aUpdater); - } - virtual void Restore(SwNode& rNd, sal_Int32 nLen, sal_Int32 nCorrLen) SAL_OVERRIDE - { - SwCntntNode* pCNd = (SwCntntNode*)rNd.GetCntntNode(); - SwDoc* pDoc = rNd.GetDoc(); - updater_t aUpdater = LimitUpdater(pCNd, nLen, nCorrLen); - RestoreBkmks(pDoc, aUpdater); - RestoreRedlines(pDoc, aUpdater); - RestoreFlys(pDoc, aUpdater, false); - RestoreUnoCrsrs(pDoc, aUpdater); - RestoreShellCrsrs(pDoc, aUpdater); - } - virtual ~CntntIdxStoreImpl(){}; - private: - inline void SaveBkmks(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt); - inline void RestoreBkmks(SwDoc* pDoc, updater_t& rUpdater); - inline void SaveRedlines(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt); - inline void RestoreRedlines(SwDoc* pDoc, updater_t& rUpdater); - inline void SaveFlys(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt, sal_uInt8 nSaveFly); - inline void RestoreFlys(SwDoc* pDoc, updater_t& rUpdater, bool bAuto); - inline void SaveUnoCrsrs(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt); - inline void RestoreUnoCrsrs(SwDoc* pDoc, updater_t& rUpdater); - inline void SaveShellCrsrs(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt); - inline void RestoreShellCrsrs(SwDoc* pDoc, updater_t& rUpdater); - inline const SwPosition& GetRightMarkPos(::sw::mark::IMark* pMark, bool bOther) - { return bOther ? pMark->GetOtherMarkPos() : pMark->GetMarkPos(); }; - inline void SetRightMarkPos(MarkBase* pMark, bool bOther, const SwPosition* const pPos) - { bOther ? pMark->SetOtherMarkPos(*pPos) : pMark->SetMarkPos(*pPos); }; - }; - static inline void lcl_ChkPaM( std::vector<PaMEntry>& rPaMEntries, const sal_uLong nNode, const sal_Int32 nCntnt, SwPaM& rPaM, const bool bPoint) - { - const SwPosition* pPos = &rPaM.GetBound( bPoint ); - if( pPos->nNode.GetIndex() == nNode && pPos->nContent.GetIndex() < nCntnt ) - { - const PaMEntry aEntry = { &rPaM, bPoint, pPos->nContent.GetIndex() }; - rPaMEntries.push_back(aEntry); - } - } - static inline void lcl_ChkPaMBoth( std::vector<PaMEntry>& rPaMEntries, const sal_uLong nNode, const sal_Int32 nCntnt, SwPaM& rPaM) - { - lcl_ChkPaM(rPaMEntries, nNode, nCntnt, rPaM, true); - lcl_ChkPaM(rPaMEntries, nNode, nCntnt, rPaM, false); - } - -#if 0 - static void DumpEntries(std::vector<MarkEntry>* pEntries) - { - BOOST_FOREACH(MarkEntry& aEntry, *pEntries) - aEntry.Dump(); - } -#endif -} - -void CntntIdxStoreImpl::SaveBkmks(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt) -{ - IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess(); - const IDocumentMarkAccess::const_iterator_t ppBkmkEnd = pMarkAccess->getAllMarksEnd(); - for( - IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->getAllMarksBegin(); - ppBkmk != ppBkmkEnd; - ++ppBkmk) - { - const ::sw::mark::IMark* pBkmk = ppBkmk->get(); - bool bMarkPosEqual = false; - if(pBkmk->GetMarkPos().nNode.GetIndex() == nNode - && pBkmk->GetMarkPos().nContent.GetIndex() <= nCntnt) - { - if(pBkmk->GetMarkPos().nContent.GetIndex() < nCntnt) - { - const MarkEntry aEntry = { ppBkmk - pMarkAccess->getAllMarksBegin(), false, pBkmk->GetMarkPos().nContent.GetIndex() }; - m_aBkmkEntries.push_back(aEntry); - } - else // if a bookmark position is equal nCntnt, the other position - bMarkPosEqual = true; // has to decide if it is added to the array - } - if(pBkmk->IsExpanded() - && pBkmk->GetOtherMarkPos().nNode.GetIndex() == nNode - && pBkmk->GetOtherMarkPos().nContent.GetIndex() <= nCntnt) - { - if(bMarkPosEqual) - { // the other position is before, the (main) position is equal - const MarkEntry aEntry = { ppBkmk - pMarkAccess->getAllMarksBegin(), false, pBkmk->GetMarkPos().nContent.GetIndex() }; - m_aBkmkEntries.push_back(aEntry); - } - const MarkEntry aEntry = { ppBkmk - pMarkAccess->getAllMarksBegin(), true, pBkmk->GetOtherMarkPos().nContent.GetIndex() }; - m_aBkmkEntries.push_back(aEntry); - } - } -} - -void CntntIdxStoreImpl::RestoreBkmks(SwDoc* pDoc, updater_t& rUpdater) -{ - IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess(); - BOOST_FOREACH(const MarkEntry& aEntry, m_aBkmkEntries) - { - if (MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getAllMarksBegin()[aEntry.m_nIdx].get())) - { - SwPosition aNewPos(GetRightMarkPos(pMark, aEntry.m_bOther)); - rUpdater(aNewPos, aEntry.m_nCntnt); - SetRightMarkPos(pMark, aEntry.m_bOther, &aNewPos); - } - } -} - -void CntntIdxStoreImpl::SaveRedlines(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt) -{ - const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl(); - for( long int nIdx = 0 ; static_cast<unsigned long int>(nIdx) < rRedlTbl.size(); ++nIdx ) - { - const SwRangeRedline* pRdl = rRedlTbl[ nIdx ]; - int nPointPos = lcl_RelativePosition( *pRdl->GetPoint(), nNode, nCntnt ); - int nMarkPos = pRdl->HasMark() ? lcl_RelativePosition( *pRdl->GetMark(), nNode, nCntnt ) : - nPointPos; - // #i59534: We have to store the positions inside the same node before the insert position - // and the one at the insert position if the corresponding Point/Mark position is before - // the insert position. - if( nPointPos == BEFORE_SAME_NODE || - ( nPointPos == SAME_POSITION && nMarkPos < SAME_POSITION ) ) - { - const MarkEntry aEntry = { nIdx, false, pRdl->GetPoint()->nContent.GetIndex() }; - m_aRedlineEntries.push_back(aEntry); - } - if( pRdl->HasMark() && ( nMarkPos == BEFORE_SAME_NODE || - ( nMarkPos == SAME_POSITION && nPointPos < SAME_POSITION ) ) ) - { - const MarkEntry aEntry = { nIdx, true, pRdl->GetMark()->nContent.GetIndex() }; - m_aRedlineEntries.push_back(aEntry); - } - } -} - -void CntntIdxStoreImpl::RestoreRedlines(SwDoc* pDoc, updater_t& rUpdater) -{ - const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl(); - SwPosition* pPos = NULL; - BOOST_FOREACH(const MarkEntry& aEntry, m_aRedlineEntries) - { - pPos = (SwPosition*)( aEntry.m_bOther - ? rRedlTbl[ aEntry.m_nIdx ]->GetMark() - : rRedlTbl[ aEntry.m_nIdx ]->GetPoint()); - rUpdater(*pPos, aEntry.m_nCntnt); - } -} - -void CntntIdxStoreImpl::SaveFlys(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt, sal_uInt8 nSaveFly) -{ - SwCntntNode *pNode = pDoc->GetNodes()[nNode]->GetCntntNode(); - if( !pNode ) - return; - SwFrm* pFrm = pNode->getLayoutFrm( pDoc->GetCurrentLayout() ); - if( pFrm ) - { - if( !pFrm->GetDrawObjs() ) - return; // if we have a layout and no DrawObjs, we can skip this - } - MarkEntry aSave; - BOOST_FOREACH(const SwFrmFmt* pFrmFmt, *pDoc->GetSpzFrmFmts()) - { - if ( RES_FLYFRMFMT == pFrmFmt->Which() || RES_DRAWFRMFMT == pFrmFmt->Which() ) - { - bool bSkip = false; - const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); - SwPosition const*const pAPos = rAnchor.GetCntntAnchor(); - if ( pAPos && ( nNode == pAPos->nNode.GetIndex() ) && - ( FLY_AT_PARA == rAnchor.GetAnchorId() || - FLY_AT_CHAR == rAnchor.GetAnchorId() ) ) - { - aSave.m_bOther = false; - aSave.m_nCntnt = pAPos->nContent.GetIndex(); - if ( FLY_AT_CHAR == rAnchor.GetAnchorId() ) - { - if( nCntnt <= aSave.m_nCntnt ) - { - if( SAVEFLY_SPLIT == nSaveFly ) - aSave.m_bOther = true; - else - bSkip = true; - } - } - if(!bSkip) - m_aFlyEntries.push_back(aSave); - } - } - ++aSave.m_nIdx; - } -} - -void CntntIdxStoreImpl::RestoreFlys(SwDoc* pDoc, updater_t& rUpdater, bool bAuto) -{ - SwFrmFmts* pSpz = pDoc->GetSpzFrmFmts(); - BOOST_FOREACH(const MarkEntry& aEntry, m_aFlyEntries) - { - if(!aEntry.m_bOther) - { - SwFrmFmt *pFrmFmt = (*pSpz)[ aEntry.m_nIdx ]; - const SwFmtAnchor& rFlyAnchor = pFrmFmt->GetAnchor(); - if( rFlyAnchor.GetCntntAnchor() ) - { - SwFmtAnchor aNew( rFlyAnchor ); - SwPosition aNewPos( *rFlyAnchor.GetCntntAnchor() ); - rUpdater(aNewPos, aEntry.m_nCntnt); - if ( FLY_AT_CHAR != rFlyAnchor.GetAnchorId() ) - { - aNewPos.nContent.Assign( 0, 0 ); - } - aNew.SetAnchor( &aNewPos ); - pFrmFmt->SetFmtAttr( aNew ); - } - } - else if( bAuto ) - { - SwFrmFmt *pFrmFmt = (*pSpz)[ aEntry.m_nIdx ]; - SfxPoolItem *pAnchor = (SfxPoolItem*)&pFrmFmt->GetAnchor(); - pFrmFmt->NotifyClients( pAnchor, pAnchor ); - } - } -} - -void CntntIdxStoreImpl::SaveUnoCrsrs(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt) -{ - BOOST_FOREACH(const SwUnoCrsr* pUnoCrsr, pDoc->GetUnoCrsrTbl()) - { - FOREACHPAM_START( const_cast<SwUnoCrsr*>(pUnoCrsr) ) - lcl_ChkPaMBoth( m_aUnoCrsrEntries, nNode, nCntnt, *PCURCRSR ); - FOREACHPAM_END() - const SwUnoTableCrsr* pUnoTblCrsr = dynamic_cast<const SwUnoTableCrsr*>(pUnoCrsr); - if( pUnoTblCrsr ) - { - FOREACHPAM_START( &(const_cast<SwUnoTableCrsr*>(pUnoTblCrsr))->GetSelRing() ) - lcl_ChkPaMBoth( m_aUnoCrsrEntries, nNode, nCntnt, *PCURCRSR ); - FOREACHPAM_END() - } - } -} - -void CntntIdxStoreImpl::RestoreUnoCrsrs(SwDoc* /* pDoc */, updater_t& rUpdater) -{ - BOOST_FOREACH(const PaMEntry& aEntry, m_aUnoCrsrEntries) - { - rUpdater(aEntry.m_pPaM->GetBound(!aEntry.m_isMark), aEntry.m_nCntnt); - } -} - -void CntntIdxStoreImpl::SaveShellCrsrs(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt) -{ - SwCrsrShell* pShell = pDoc->GetEditShell(); - if( !pShell ) - return; - SwViewShell *_pStartShell = pShell; - do { - if( _pStartShell->IsA( TYPE( SwCrsrShell )) ) - { - SwPaM *_pStkCrsr = ((SwCrsrShell*)_pStartShell)->GetStkCrsr(); - if( _pStkCrsr ) - do { - lcl_ChkPaMBoth( m_aShellCrsrEntries, nNode, nCntnt, *_pStkCrsr); - } while ( (_pStkCrsr != 0 ) && - ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != ((SwCrsrShell*)_pStartShell)->GetStkCrsr()) ); - - FOREACHPAM_START( ((SwCrsrShell*)_pStartShell)->_GetCrsr() ) - lcl_ChkPaMBoth( m_aShellCrsrEntries, nNode, nCntnt, *PCURCRSR); - FOREACHPAM_END() - } - } while((_pStartShell=(SwViewShell*)_pStartShell->GetNext())!= pShell ); -} - -void CntntIdxStoreImpl::RestoreShellCrsrs(SwDoc* /* pDoc */, updater_t& rUpdater) -{ - BOOST_FOREACH(const PaMEntry& aEntry, m_aShellCrsrEntries) - { - rUpdater(aEntry.m_pPaM->GetBound(aEntry.m_isMark), aEntry.m_nCntnt); - } -} - -namespace sw { namespace mark { - boost::shared_ptr<CntntIdxStore> CntntIdxStore::Create() - { - return boost::shared_ptr<CntntIdxStore>(new CntntIdxStoreImpl()); - } -}} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |