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

Reply via email to