diff options
-rw-r--r-- | sw/inc/ndtxt.hxx | 3 | ||||
-rw-r--r-- | sw/source/core/inc/wrong.hxx | 36 | ||||
-rw-r--r-- | sw/source/core/text/wrong.cxx | 195 | ||||
-rw-r--r-- | sw/source/core/txtnode/txtedt.cxx | 10 |
4 files changed, 244 insertions, 0 deletions
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx index 894f8c078635..d1a8801eb9c7 100644 --- a/sw/inc/ndtxt.hxx +++ b/sw/inc/ndtxt.hxx @@ -194,8 +194,11 @@ public: const SwWrongList* GetWrong() const; void SetGrammarCheck( SwGrammarMarkUp* pNew, bool bDelete = true ); SwGrammarMarkUp* GetGrammarCheck(); + // return SwWrongList because *function pointer* return values aren't covariant + SwWrongList const* GetGrammarCheck() const; void SetSmartTags( SwWrongList* pNew, bool bDelete = true ); SwWrongList* GetSmartTags(); + SwWrongList const* GetSmartTags() const; void TryCharSetExpandToNum(const SfxItemSet& pCharSet); /// End: Data collected during idle time diff --git a/sw/source/core/inc/wrong.hxx b/sw/source/core/inc/wrong.hxx index 0aa575434483..831c5bb7f99a 100644 --- a/sw/source/core/inc/wrong.hxx +++ b/sw/source/core/inc/wrong.hxx @@ -32,6 +32,7 @@ #include <tools/color.hxx> #include <swtypes.hxx> #include <viewopt.hxx> +#include "TextFrameIndex.hxx" class SwWrongList; @@ -331,6 +332,41 @@ public: bool LookForEntry( sal_Int32 nBegin, sal_Int32 nEnd ); }; +class SwTextNode; +class SwTextFrame; + +namespace sw { + +struct MergedPara; + +class WrongListIterator +{ +private: + SwWrongList const* (SwTextNode::*const m_pGetWrongList)() const; + sw::MergedPara const*const m_pMergedPara; + size_t m_CurrentExtent; + TextFrameIndex m_CurrentIndex; + TextFrameIndex m_CurrentNodeIndex; + SwWrongList const*const m_pWrongList; + +public: + /// for the text frame + WrongListIterator(SwTextFrame const& rFrame, + SwWrongList const* (SwTextNode::*pGetWrongList)() const); + /// for SwTextSlot + WrongListIterator(SwWrongList const& rWrongList); + + bool Check(TextFrameIndex &rStart, TextFrameIndex &rLen); + const SwWrongArea* GetWrongElement(TextFrameIndex nStart); + + bool LooksUseful() { return m_pMergedPara || m_pWrongList; } + bool MergedOrSame(SwWrongList const*const pList) const { + return m_pMergedPara || m_pWrongList == pList; + } +}; + +} // namespace sw + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/text/wrong.cxx b/sw/source/core/text/wrong.cxx index 20fdac821985..bdad843a43f8 100644 --- a/sw/source/core/text/wrong.cxx +++ b/sw/source/core/text/wrong.cxx @@ -20,6 +20,9 @@ #include <swtypes.hxx> #include <SwGrammarMarkUp.hxx> +#include <ndtxt.hxx> +#include <txtfrm.hxx> + #include <osl/diagnose.h> SwWrongArea::SwWrongArea( const OUString& rType, WrongListType listType, @@ -659,4 +662,196 @@ void SwWrongList::Insert( const OUString& rType, maList.insert(aIter, SwWrongArea( rType, meType, xPropertyBag, nNewPos, nNewLen) ); } +namespace sw { + +WrongListIterator::WrongListIterator(SwTextFrame const& rFrame, + SwWrongList const* (SwTextNode::*pGetWrongList)() const) + : m_pGetWrongList(pGetWrongList) + , m_pMergedPara(rFrame.GetMergedPara()) + , m_CurrentExtent(0) + , m_CurrentIndex(0) + , m_CurrentNodeIndex(0) + , m_pWrongList(m_pMergedPara + ? nullptr + : (rFrame.GetTextNodeFirst()->*pGetWrongList)()) +{ +} + +WrongListIterator::WrongListIterator(SwWrongList const& rWrongList) + : m_pGetWrongList(nullptr) + , m_pMergedPara(nullptr) + , m_CurrentExtent(0) + , m_CurrentIndex(0) + , m_CurrentNodeIndex(0) + , m_pWrongList(&rWrongList) +{ +} + +bool WrongListIterator::Check(TextFrameIndex & rStart, TextFrameIndex & rLen) +{ + if (m_pMergedPara) + { + if (rStart < m_CurrentIndex) + { // rewind + m_CurrentExtent = 0; + m_CurrentIndex = TextFrameIndex(0); + m_CurrentNodeIndex = TextFrameIndex(0); + } + while (m_CurrentExtent < m_pMergedPara->extents.size()) + { + sw::Extent const& rExtent(m_pMergedPara->extents[m_CurrentExtent]); + if (rStart + rLen <= m_CurrentIndex) + { + return false; + } + else if (rStart < m_CurrentIndex) + { + rLen -= (m_CurrentIndex - rStart); + assert(0 < sal_Int32(rLen)); + rStart = m_CurrentIndex; + } + if (m_CurrentIndex <= rStart && + rStart < m_CurrentIndex + TextFrameIndex(rExtent.nEnd - rExtent.nStart)) + { + SwWrongList const*const pWrongList((rExtent.pNode->*m_pGetWrongList)()); + // found the extent containing start - first, call Check + sal_Int32 nStart(rExtent.nStart + sal_Int32(rStart - m_CurrentIndex)); // (m_CurrentIndex - m_CurrentNodeIndex)); + sal_Int32 nLen; + if (sal_Int32(rLen) < rExtent.nEnd - nStart) + { + nLen = sal_Int32(rLen); + } + else + { + sal_Int32 nInLen(rLen); + nLen = rExtent.nEnd - nStart; + nInLen -= nLen; + for (size_t i = m_CurrentExtent + 1; + i < m_pMergedPara->extents.size(); ++i) + { + sw::Extent const& rExtentEnd(m_pMergedPara->extents[i]); + if (rExtentEnd.pNode != rExtent.pNode) + { + nInLen = 0; + break; + } + // add gap too + nLen += rExtentEnd.nStart - m_pMergedPara->extents[i-1].nEnd; + if (nInLen <= rExtentEnd.nEnd - rExtentEnd.nStart) + { + nLen += nInLen; + nInLen = 0; + break; + } + nLen += rExtentEnd.nEnd - rExtentEnd.nStart; + nInLen -= rExtentEnd.nEnd - rExtentEnd.nStart; + } + } + if (pWrongList && pWrongList->Check(nStart, nLen)) + { + // check if there's overlap with this extent + if (rExtent.nStart <= nStart && nStart < rExtent.nEnd) + { + // yes - now compute end position / length + sal_Int32 const nEnd(nStart + nLen); + rStart = m_CurrentIndex + TextFrameIndex(nStart - rExtent.nStart); + TextFrameIndex const nOrigLen(rLen); + if (nEnd <= rExtent.nEnd) + { + rLen = TextFrameIndex(nEnd - nStart); + } + else // have to search other extents for the end... + { + rLen = TextFrameIndex(rExtent.nEnd - nStart); + for (size_t i = m_CurrentExtent + 1; + i < m_pMergedPara->extents.size(); ++i) + { + sw::Extent const& rExtentEnd(m_pMergedPara->extents[i]); + if (rExtentEnd.pNode != rExtent.pNode + || nEnd <= rExtentEnd.nStart) + { + break; + } + if (nEnd <= rExtentEnd.nEnd) + { + rLen += TextFrameIndex(nEnd - rExtentEnd.nStart); + break; + } + rLen += TextFrameIndex(rExtentEnd.nEnd - rExtentEnd.nStart); + } + } + assert(rLen <= nOrigLen); (void) nOrigLen; + return true; + } + } + } + m_CurrentIndex += TextFrameIndex(rExtent.nEnd - rExtent.nStart); + ++m_CurrentExtent; + if (m_CurrentExtent < m_pMergedPara->extents.size() && + rExtent.pNode != m_pMergedPara->extents[m_CurrentExtent].pNode) + { + m_CurrentNodeIndex = m_CurrentIndex; // reset + } + } + return false; + } + else if (m_pWrongList) + { + sal_Int32 nStart(rStart); + sal_Int32 nLen(rLen); + bool const bRet(m_pWrongList->Check(nStart, nLen)); + rStart = TextFrameIndex(nStart); + rLen = TextFrameIndex(nLen); + return bRet; + } + return false; +} + +const SwWrongArea* +WrongListIterator::GetWrongElement(TextFrameIndex const nStart) +{ + if (m_pMergedPara) + { + if (nStart < m_CurrentIndex) + { // rewind + m_CurrentExtent = 0; + m_CurrentIndex = TextFrameIndex(0); + m_CurrentNodeIndex = TextFrameIndex(0); + } + while (m_CurrentExtent < m_pMergedPara->extents.size()) + { + sw::Extent const& rExtent(m_pMergedPara->extents[m_CurrentExtent]); + if (m_CurrentIndex <= nStart && + nStart <= m_CurrentIndex + TextFrameIndex(rExtent.nEnd - rExtent.nStart)) + { + // note: the returned object isn't wrapped because fntcache.cxx + // does not look at its positions, only its formatting props + SwWrongList const*const pWrongList((rExtent.pNode->*m_pGetWrongList)()); + if (pWrongList) + { + sal_Int32 const nNStart(rExtent.nStart + sal_Int32(nStart - m_CurrentIndex)); // (m_CurrentIndex - m_CurrentNodeIndex)); + sal_Int16 const nPos(pWrongList->GetWrongPos(nNStart)); + return pWrongList->GetElement(nPos); + } + } + m_CurrentIndex += TextFrameIndex(rExtent.nEnd - rExtent.nStart); + ++m_CurrentExtent; + if (m_CurrentExtent < m_pMergedPara->extents.size() && + rExtent.pNode != m_pMergedPara->extents[m_CurrentExtent].pNode) + { + m_CurrentNodeIndex = m_CurrentIndex; // reset + } + } + return nullptr; + } + else if (m_pWrongList) + { + sal_Int16 const nPos(m_pWrongList->GetWrongPos(sal_Int32(nStart))); + return m_pWrongList->GetElement(nPos); + } + return nullptr; +} + +} // namespace sw + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx index 1f1468b1429d..7a646fc2b8ed 100644 --- a/sw/source/core/txtnode/txtedt.cxx +++ b/sw/source/core/txtnode/txtedt.cxx @@ -2216,6 +2216,11 @@ SwGrammarMarkUp* SwTextNode::GetGrammarCheck() return m_pParaIdleData_Impl ? m_pParaIdleData_Impl->pGrammarCheck : nullptr; } +SwWrongList const* SwTextNode::GetGrammarCheck() const +{ + return static_cast<SwWrongList const*>(const_cast<SwTextNode*>(this)->GetGrammarCheck()); +} + void SwTextNode::SetSmartTags( SwWrongList* pNew, bool bDelete ) { OSL_ENSURE( !pNew || SwSmartTagMgr::Get().IsSmartTagsEnabled(), @@ -2236,6 +2241,11 @@ SwWrongList* SwTextNode::GetSmartTags() return m_pParaIdleData_Impl ? m_pParaIdleData_Impl->pSmartTags : nullptr; } +SwWrongList const* SwTextNode::GetSmartTags() const +{ + return const_cast<SwWrongList const*>(const_cast<SwTextNode*>(this)->GetSmartTags()); +} + void SwTextNode::SetWordCountDirty( bool bNew ) const { if ( m_pParaIdleData_Impl ) |