sw/source/core/crsr/crsrsh.cxx | 2 sw/source/core/inc/txtfrm.hxx | 10 ++-- sw/source/core/text/itrform2.cxx | 4 - sw/source/core/text/itrform2.hxx | 4 + sw/source/core/text/txtfld.cxx | 28 +++++------ sw/source/core/text/txtfrm.cxx | 92 +++++++++++++++++++------------------ sw/source/uibase/docvw/edtwin2.cxx | 2 7 files changed, 75 insertions(+), 67 deletions(-)
New commits: commit 2b4a88209245c252143a7439473d7e486dd5a3fa Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Thu Oct 11 18:03:27 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Oct 12 10:45:13 2018 +0200 sw_redlinehide_3: rewrite MergedAttrIterByEnd It doesn't actually work with a similar logic to the other iterators, because it iterates ByEnd but forwards, so the hints and the extents don't come in a matching order. To prevent complicating this further, replace it with a new implementation that does only what the one client expects, and put it directly in SwTextFormatter replacing the previous integer iterator m_nHintEndIndex, so that it is created only once. Change-Id: I144bfcf7e837a4fb0e7ec279edfba4732d0ae897 diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index 0cb3f3defe83..f537a98d0f95 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -971,11 +971,15 @@ public: }; class MergedAttrIterByEnd - : public MergedAttrIterBase { +private: + std::vector<std::pair<SwTextNode const*, SwTextAttr const*>> m_Hints; + SwTextNode const*const m_pNode; + size_t m_CurrentHint; public: - MergedAttrIterByEnd(SwTextFrame const& rFrame) : MergedAttrIterBase(rFrame) {} - SwTextAttr const* NextAttr(SwTextNode const** ppNode = nullptr); + MergedAttrIterByEnd(SwTextFrame const& rFrame); + SwTextAttr const* NextAttr(SwTextNode const*& rpNode); + void PrevAttr(); }; class MergedAttrIterReverse diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 16d35e581131..879da6c822d9 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -97,7 +97,7 @@ void SwTextFormatter::CtorInitTextFormatter( SwTextFrame *pNewFrame, SwTextForma nCntMidHyph = 0; nLeftScanIdx = TextFrameIndex(COMPLETE_STRING); nRightScanIdx = TextFrameIndex(0); - m_nHintEndIndex = 0; + m_pByEndIter.reset(); m_pFirstOfBorderMerge = nullptr; if (m_nStart > TextFrameIndex(GetInfo().GetText().getLength())) @@ -289,7 +289,7 @@ SwLinePortion *SwTextFormatter::Underflow( SwTextFormatInfo &rInf ) static_cast<SwFieldPortion*>(pRest)->IsNoLength()) { // HACK: decrement again, so we pick up the suffix in next line! - --m_nHintEndIndex; + m_pByEndIter->PrevAttr(); } delete pRest; rInf.SetRest(nullptr); diff --git a/sw/source/core/text/itrform2.hxx b/sw/source/core/text/itrform2.hxx index ff430b8616d1..555fed20cdcc 100644 --- a/sw/source/core/text/itrform2.hxx +++ b/sw/source/core/text/itrform2.hxx @@ -31,6 +31,8 @@ class SwExpandPortion; class SwMultiPortion; class SwFootnotePortion; +namespace sw { class MergedAttrIterByEnd; } + class SwTextFormatter : public SwTextPainter { const SwFormatDrop *pDropFormat; @@ -43,7 +45,7 @@ class SwTextFormatter : public SwTextPainter bool bFlyInCntBase : 1; // Base reference that sets a character-bound frame bool bTruncLines : 1; // Flag for extending the repaint rect, if needed bool bUnclipped : 1; // Flag whether repaint is larger than the fixed line height - size_t m_nHintEndIndex; // HACK for TryNewNoLengthPortion + std::unique_ptr<sw::MergedAttrIterByEnd> m_pByEndIter; // HACK for TryNewNoLengthPortion SwLinePortion* m_pFirstOfBorderMerge; // The first text portion of a joined border (during portion building) SwLinePortion *NewPortion( SwTextFormatInfo &rInf ); diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx index b70b4bc7456b..196b11b84cf9 100644 --- a/sw/source/core/text/txtfld.cxx +++ b/sw/source/core/text/txtfld.cxx @@ -307,9 +307,9 @@ static SwFieldPortion * lcl_NewMetaPortion(SwTextAttr & rHint, const bool bPrefi /** * Try to create a new portion with zero length, for an end of a hint * (where there is no CH_TXTATR). Because there may be multiple hint ends at a - * given index, m_nHintEndIndex is used to keep track of the already created + * given index, m_pByEndIter is used to keep track of the already created * portions. But the portions created here may actually be deleted again, - * due to Underflow. In that case, m_nHintEndIndex must be decremented, + * due to Underflow. In that case, m_pByEndIter must be decremented, * so the portion will be created again on the next line. */ SwExpandPortion * SwTextFormatter::TryNewNoLengthPortion(SwTextFormatInfo const & rInfo) @@ -319,26 +319,24 @@ SwExpandPortion * SwTextFormatter::TryNewNoLengthPortion(SwTextFormatInfo const // sw_redlinehide: because there is a dummy character at the start of these // hints, it's impossible to have ends of hints from different nodes at the // same view position, so it's sufficient to check the hints of the current - // node. However, m_nHintEndIndex exists for the whole text frame, so + // node. However, m_pByEndIter exists for the whole text frame, so // it's necessary to iterate all hints for that purpose... + if (!m_pByEndIter) + { + m_pByEndIter.reset(new sw::MergedAttrIterByEnd(*rInfo.GetTextFrame())); + } SwTextNode const* pNode(nullptr); - sw::MergedAttrIterByEnd iter(*rInfo.GetTextFrame()); - size_t i(0); - for (SwTextAttr const* pHint = iter.NextAttr(&pNode); pHint; - pHint = iter.NextAttr(&pNode)) + for (SwTextAttr const* pHint = m_pByEndIter->NextAttr(pNode); pHint; + pHint = m_pByEndIter->NextAttr(pNode)) { - if (i++ < m_nHintEndIndex) - { - continue; // skip ones that were handled earlier - } SwTextAttr & rHint(const_cast<SwTextAttr&>(*pHint)); TextFrameIndex const nEnd( rInfo.GetTextFrame()->MapModelToView(pNode, *rHint.GetAnyEnd())); if (nEnd > nIdx) { + m_pByEndIter->PrevAttr(); break; } - ++m_nHintEndIndex; if (nEnd == nIdx) { if (RES_TXTATR_METAFIELD == rHint.Which()) diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index a81a7df905d6..a07d712cd4c7 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -153,44 +153,24 @@ namespace sw { } } - SwTextAttr const* MergedAttrIterByEnd::NextAttr(SwTextNode const** ppNode) + MergedAttrIterByEnd::MergedAttrIterByEnd(SwTextFrame const& rFrame) + : m_pNode(rFrame.GetMergedPara() ? nullptr : rFrame.GetTextNodeFirst()) + , m_CurrentHint(0) { - if (m_pMerged) + if (!m_pNode) { - while (m_CurrentExtent < m_pMerged->extents.size()) + MergedAttrIterReverse iter(rFrame); + SwTextNode const* pNode(nullptr); + while (SwTextAttr const* pHint = iter.PrevAttr(&pNode)) { - sw::Extent const& rExtent(m_pMerged->extents[m_CurrentExtent]); - if (SwpHints const*const pHints = rExtent.pNode->GetpSwpHints()) - { - while (m_CurrentHint < pHints->Count()) - { - SwTextAttr const*const pHint( - pHints->GetSortedByEnd(m_CurrentHint)); - if (rExtent.nEnd <= *pHint->GetAnyEnd()) - { - break; - } - ++m_CurrentHint; - if (rExtent.nStart < *pHint->GetAnyEnd()) - { - if (ppNode) - { - *ppNode = rExtent.pNode; - } - return pHint; - } - } - } - ++m_CurrentExtent; - if (m_CurrentExtent < m_pMerged->extents.size() && - rExtent.pNode != m_pMerged->extents[m_CurrentExtent].pNode) - { - m_CurrentHint = 0; // reset - } + m_Hints.emplace_back(pNode, pHint); } - return nullptr; } - else + } + + SwTextAttr const* MergedAttrIterByEnd::NextAttr(SwTextNode const*& rpNode) + { + if (m_pNode) { SwpHints const*const pHints(m_pNode->GetpSwpHints()); if (pHints) @@ -200,15 +180,29 @@ namespace sw { SwTextAttr const*const pHint( pHints->GetSortedByEnd(m_CurrentHint)); ++m_CurrentHint; - if (ppNode) - { - *ppNode = m_pNode; - } + rpNode = m_pNode; return pHint; } } return nullptr; } + else + { + if (m_CurrentHint < m_Hints.size()) + { + auto const ret = m_Hints[m_Hints.size() - m_CurrentHint - 1]; + ++m_CurrentHint; + rpNode = ret.first; + return ret.second; + } + return nullptr; + } + } + + void MergedAttrIterByEnd::PrevAttr() + { + assert(0 < m_CurrentHint); // should only rewind as far as 0 + --m_CurrentHint; } MergedAttrIterReverse::MergedAttrIterReverse(SwTextFrame const& rFrame) commit 60d6db937be640c625dc16f965a2f877cdd026af Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Thu Oct 11 12:41:32 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Oct 12 10:45:13 2018 +0200 sw_redlinehide_3: fix MergedAttrIterReverse Was using the wrong node when iterating; also the tricky case of empty or without-end hints at the start of an extent was wrong. MergedAttrIter also shouldn't include wihout-end hints and non-empty hints at the end of an extent. Change-Id: Ia0776c1d3043cbd6d76fa04905b4937ebba53398 diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx index e66b7ed2c884..b70b4bc7456b 100644 --- a/sw/source/core/text/txtfld.cxx +++ b/sw/source/core/text/txtfld.cxx @@ -424,9 +424,9 @@ static void checkApplyParagraphMarkFormatToNumbering( SwFont* pNumFnt, SwTextFor for (SwTextAttr const* pHint = iter.PrevAttr(&pNode); pHint; pHint = iter.PrevAttr(&pNode)) { - TextFrameIndex const nHintStart( - rInf.GetTextFrame()->MapModelToView(pNode, pHint->GetStart())); - if (nHintStart < nTextLen) + TextFrameIndex const nHintEnd( + rInf.GetTextFrame()->MapModelToView(pNode, *pHint->GetAnyEnd())); + if (nHintEnd < nTextLen) { break; // only those at para end are interesting } diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index 5603d7800914..a81a7df905d6 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -104,8 +104,12 @@ namespace sw { { while (m_CurrentHint < pHints->Count()) { - SwTextAttr const*const pHint(pHints->Get(m_CurrentHint)); - if (rExtent.nEnd < pHint->GetStart()) + SwTextAttr *const pHint(pHints->Get(m_CurrentHint)); + if (rExtent.nEnd < pHint->GetStart() + // <= if it has no end or isn't empty + || (rExtent.nEnd == pHint->GetStart() + && (!pHint->GetEnd() + || *pHint->GetEnd() != pHint->GetStart()))) { break; } @@ -238,13 +242,18 @@ namespace sw { { while (0 < m_CurrentHint) { - SwTextAttr const*const pHint(pHints->Get(m_CurrentHint - 1)); - if (pHint->GetStart() < rExtent.nStart) + SwTextAttr *const pHint( + pHints->GetSortedByEnd(m_CurrentHint - 1)); + if (*pHint->GetAnyEnd() < rExtent.nStart + // <= if it has end and isn't empty + || (pHint->GetEnd() + && *pHint->GetEnd() != pHint->GetStart() + && *pHint->GetEnd() == rExtent.nStart)) { break; } --m_CurrentHint; - if (pHint->GetStart() <= rExtent.nEnd) + if (*pHint->GetAnyEnd() <= rExtent.nEnd) { if (ppNode) { @@ -258,7 +267,8 @@ namespace sw { if (0 < m_CurrentExtent && rExtent.pNode != m_pMerged->extents[m_CurrentExtent-1].pNode) { - SwpHints const*const pHints(rExtent.pNode->GetpSwpHints()); + SwpHints const*const pHints( + m_pMerged->extents[m_CurrentExtent-1].pNode->GetpSwpHints()); m_CurrentHint = pHints ? pHints->Count() : 0; // reset } } @@ -271,7 +281,7 @@ namespace sw { { while (0 < m_CurrentHint) { - SwTextAttr const*const pHint(pHints->Get(m_CurrentHint - 1)); + SwTextAttr const*const pHint(pHints->GetSortedByEnd(m_CurrentHint - 1)); --m_CurrentHint; if (ppNode) { commit 3899c75add665889cf3eb0411ed72051fa056ca9 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Thu Oct 11 11:17:09 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Thu Oct 11 12:31:13 2018 +0200 sw_redlinehide_3: fix typo bug in SwCursorShell::GetSelText() Change-Id: Ieee07d149d045b7953ea8d5489f2fb6aed13e5e4 diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx index 565acb6d60fd..42febd5f6271 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -2428,7 +2428,7 @@ OUString SwCursorShell::GetSelText() const : 0); sal_Int32 const nEnd(i == pEnd->nNode.GetIndex() ? pEnd->nContent.GetIndex() - : pEnd->nNode.GetNode().GetTextNode()->Len()); + : rNode.GetTextNode()->Len()); buf.append(rNode.GetTextNode()->GetExpandText( nStart, nEnd - nStart, false, false, false, ExpandMode::HideDeletions)); commit f72b286d6e285e84a02d0a3ebd8ce43e6d0b54ce Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Thu Oct 11 10:54:30 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Thu Oct 11 10:54:30 2018 +0200 sw: fix invalid cast in SwEditWin::RequestHelp() This results in a garbage OUString. Change-Id: Ica1296ecbba3f5c27619d494d3b41752d40a3150 diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx index fe3f1021b4ef..e2049a33be52 100644 --- a/sw/source/uibase/docvw/edtwin2.cxx +++ b/sw/source/uibase/docvw/edtwin2.cxx @@ -169,7 +169,7 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) case IsAttrAtPos::InetAttr: { - sText = static_cast<const SfxStringItem*>(aContentAtPos.aFnd.pAttr)->GetValue(); + sText = static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr)->GetValue(); sText = URIHelper::removePassword( sText, INetURLObject::EncodeMechanism::WasEncoded, INetURLObject::DecodeMechanism::Unambiguous); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits