summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern Michaelsen <bjoern.michaelsen@canonical.com>2014-07-25 00:39:54 +0200
committerBjoern Michaelsen <bjoern.michaelsen@canonical.com>2014-07-25 09:47:53 +0200
commitfec5892741df952ebf97ea745fce3d061c75de34 (patch)
tree323f9daa61408376f9a01fdbf0b8da29dafa9790
parent6c1f2ea2aa11b2c8fd42b455c7c452194ed2c1e7 (diff)
move CntntIdxStore to own file
Change-Id: Ic8280478b154b9b132f74e260edea46911cb1803
-rw-r--r--sw/Library_sw.mk1
-rw-r--r--sw/source/core/doc/CntntIdxStore.cxx455
-rw-r--r--sw/source/core/doc/docbm.cxx400
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: */