[Libreoffice-commits] core.git: 2 commits - sw/source
Michael Stahl (via logerrit)
logerrit at kemper.freedesktop.org
Tue Nov 17 21:20:00 UTC 2020
sw/source/core/layout/wsfrm.cxx | 10 +-
sw/source/core/text/redlnitr.cxx | 181 +++++++++++++++++++++++++++++++++------
2 files changed, 162 insertions(+), 29 deletions(-)
New commits:
commit aacaa2aa91f705d64b929b5cff2872f160021b9f
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Nov 3 22:11:59 2020 +0100
Commit: Michael Stahl <michael.stahl at cib.de>
CommitDate: Tue Nov 17 22:19:32 2020 +0100
sw_fieldmarkhide: let CheckParaRedlineMerge() hide fieldmarks
HideIterator finds the next delete redline or fieldmark, whichever is
closer.
Change-Id: I4c6eac864da4b4bf531437e555a3994fd2670367
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105984
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx
index 6727751c3576..a79ce4878a89 100644
--- a/sw/source/core/text/redlnitr.cxx
+++ b/sw/source/core/text/redlnitr.cxx
@@ -35,6 +35,9 @@
#include <doc.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <IDocumentLayoutAccess.hxx>
+#include <IDocumentMarkAccess.hxx>
+#include <IMark.hxx>
+#include <bookmrk.hxx>
#include <rootfrm.hxx>
#include <breakit.hxx>
#include <vcl/commandevent.hxx>
@@ -47,14 +50,161 @@
using namespace ::com::sun::star;
+namespace {
+
+class HideIterator
+{
+private:
+ IDocumentRedlineAccess const& m_rIDRA;
+ IDocumentMarkAccess const& m_rIDMA;
+ bool const m_isHideRedlines;
+ sw::FieldmarkMode const m_eFieldmarkMode;
+ SwPosition const m_Start;
+ /// next redline
+ SwRedlineTable::size_type m_RedlineIndex;
+ /// next fieldmark
+ std::pair<sw::mark::IFieldmark const*, std::unique_ptr<SwPosition>> m_Fieldmark;
+ std::optional<SwPosition> m_oNextFieldmarkHide;
+ /// current start/end pair
+ SwPosition const* m_pStartPos;
+ SwPosition const* m_pEndPos;
+
+public:
+ SwPosition const* GetStartPos() const { return m_pStartPos; }
+ SwPosition const* GetEndPos() const { return m_pEndPos; }
+
+ HideIterator(SwTextNode & rTextNode,
+ bool const isHideRedlines, sw::FieldmarkMode const eMode)
+ : m_rIDRA(rTextNode.getIDocumentRedlineAccess())
+ , m_rIDMA(*rTextNode.getIDocumentMarkAccess())
+ , m_isHideRedlines(isHideRedlines)
+ , m_eFieldmarkMode(eMode)
+ , m_Start(rTextNode, 0)
+ , m_RedlineIndex(m_rIDRA.GetRedlinePos(rTextNode, RedlineType::Any))
+ , m_pStartPos(nullptr)
+ , m_pEndPos(&m_Start)
+ {
+ }
+
+ // delete redlines and fieldmarks can't overlap, due to sw::CalcBreaks()
+ // and no combining of adjacent redlines
+ // -> dummy chars are delete-redlined *iff* entire fieldmark is
+ // Note: caller is responsible for checking for immediately adjacent hides
+ bool Next()
+ {
+ SwPosition const* pNextRedlineHide(nullptr);
+ assert(m_pEndPos);
+ if (m_isHideRedlines)
+ {
+ // position on current or next redline
+ for (; m_RedlineIndex < m_rIDRA.GetRedlineTable().size(); ++m_RedlineIndex)
+ {
+ SwRangeRedline const*const pRed = m_rIDRA.GetRedlineTable()[m_RedlineIndex];
+
+ if (m_pEndPos->nNode.GetIndex() < pRed->Start()->nNode.GetIndex())
+ break;
+
+ if (pRed->GetType() != RedlineType::Delete)
+ continue;
+
+ SwPosition const*const pStart(pRed->Start());
+ SwPosition const*const pEnd(pRed->End());
+ if (*pStart == *pEnd)
+ { // only allowed while moving (either way?)
+// assert(IDocumentRedlineAccess::IsHideChanges(rIDRA.GetRedlineFlags()));
+ continue;
+ }
+ if (pStart->nNode.GetNode().IsTableNode())
+ {
+ assert(pEnd->nNode == m_Start.nNode && pEnd->nContent.GetIndex() == 0);
+ continue; // known pathology, ignore it
+ }
+ if (*m_pEndPos <= *pStart)
+ {
+ pNextRedlineHide = pStart;
+ break; // the next one
+ }
+ }
+ }
+
+ // position on current or next fieldmark
+ m_oNextFieldmarkHide.reset();
+ if (m_eFieldmarkMode != sw::FieldmarkMode::ShowBoth)
+ {
+ sal_Unicode const magic(m_eFieldmarkMode == sw::FieldmarkMode::ShowResult
+ ? CH_TXT_ATR_FIELDSTART
+ : CH_TXT_ATR_FIELDSEP);
+ sal_Int32 const nPos(m_pEndPos->nNode.GetNode().GetTextNode()->GetText().indexOf(
+ magic, m_pEndPos->nContent.GetIndex()));
+ if (nPos != -1)
+ {
+ m_oNextFieldmarkHide.emplace(*m_pEndPos->nNode.GetNode().GetTextNode(), nPos);
+ sw::mark::IFieldmark const*const pFieldmark(
+ m_eFieldmarkMode == sw::FieldmarkMode::ShowResult
+ ? m_rIDMA.getFieldmarkAt(*m_oNextFieldmarkHide)
+ : m_rIDMA.getFieldmarkFor(*m_oNextFieldmarkHide));
+ assert(pFieldmark);
+ m_Fieldmark.first = pFieldmark;
+ // for cursor travelling, there should be 2 visible chars;
+ // whichever char is hidden, the cursor travelling needs to
+ // be adapted in any case to skip in some situation or other;
+ // always hide the CH_TXT_ATR_FIELDSEP for now
+ if (m_eFieldmarkMode == sw::FieldmarkMode::ShowResult)
+ {
+ m_Fieldmark.second.reset(
+ new SwPosition(sw::mark::FindFieldSep(*m_Fieldmark.first)));
+ ++m_Fieldmark.second->nContent;
+ ++m_oNextFieldmarkHide->nContent; // skip start
+ }
+ else
+ {
+ m_Fieldmark.second.reset(
+ new SwPosition(pFieldmark->GetMarkEnd()));
+ --m_Fieldmark.second->nContent;
+ }
+ }
+ }
+
+ // == can happen only if redline starts inside field command, and in
+ // that case redline will end before field separator
+ assert(!pNextRedlineHide || !m_oNextFieldmarkHide
+ || *pNextRedlineHide != *m_oNextFieldmarkHide
+ || *m_rIDRA.GetRedlineTable()[m_RedlineIndex]->End() < *m_Fieldmark.second);
+ if (pNextRedlineHide
+ && (!m_oNextFieldmarkHide || *pNextRedlineHide < *m_oNextFieldmarkHide))
+ {
+ SwRangeRedline const*const pRed(m_rIDRA.GetRedlineTable()[m_RedlineIndex]);
+ m_pStartPos = pRed->Start();
+ m_pEndPos = pRed->End();
+ ++m_RedlineIndex;
+ return true;
+ }
+ else if (m_oNextFieldmarkHide)
+ {
+ assert(!pNextRedlineHide || *m_oNextFieldmarkHide < *pNextRedlineHide);
+ m_pStartPos = &*m_oNextFieldmarkHide;
+ m_pEndPos = m_Fieldmark.second.get();
+ return true;
+ }
+ else // nothing
+ {
+ assert(!pNextRedlineHide && !m_oNextFieldmarkHide);
+ m_pStartPos = nullptr;
+ m_pEndPos = nullptr;
+ return false;
+ }
+ }
+};
+
+}
+
namespace sw {
std::unique_ptr<sw::MergedPara>
CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode,
FrameMode const eMode)
{
- IDocumentRedlineAccess const& rIDRA = rTextNode.getIDocumentRedlineAccess();
- if (!rFrame.getRootFrame()->IsHideRedlines())
+ if (!rFrame.getRootFrame()->HasMergedParas())
{
return nullptr;
}
@@ -67,29 +217,12 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode,
SwTextNode * pParaPropsNode(nullptr);
SwTextNode * pNode(&rTextNode);
sal_Int32 nLastEnd(0);
- for (auto i = rIDRA.GetRedlinePos(rTextNode, RedlineType::Any);
- i < rIDRA.GetRedlineTable().size(); ++i)
+ for (auto iter = HideIterator(rTextNode,
+ rFrame.getRootFrame()->IsHideRedlines(),
+ rFrame.getRootFrame()->GetFieldmarkMode()); iter.Next(); )
{
- SwRangeRedline const*const pRed = rIDRA.GetRedlineTable()[i];
-
- if (pNode->GetIndex() < pRed->Start()->nNode.GetIndex())
- break;
-
- if (pRed->GetType() != RedlineType::Delete)
- continue;
-
- SwPosition const*const pStart(pRed->Start());
- SwPosition const*const pEnd(pRed->End());
- if (*pStart == *pEnd)
- { // only allowed while moving (either way?)
-// assert(IDocumentRedlineAccess::IsHideChanges(rIDRA.GetRedlineFlags()));
- continue;
- }
- if (pStart->nNode.GetNode().IsTableNode())
- {
- assert(&pEnd->nNode.GetNode() == &rTextNode && pEnd->nContent.GetIndex() == 0);
- continue; // known pathology, ignore it
- }
+ SwPosition const*const pStart(iter.GetStartPos());
+ SwPosition const*const pEnd(iter.GetEndPos());
bHaveRedlines = true;
assert(pNode != &rTextNode || &pStart->nNode.GetNode() == &rTextNode); // detect calls with wrong start node
if (pStart->nContent != nLastEnd) // not 0 so we eliminate adjacent deletes
commit c33c0a16ec781926b752f0589e6eca6f4e63a1e3
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Nov 17 12:43:03 2020 +0100
Commit: Michael Stahl <michael.stahl at cib.de>
CommitDate: Tue Nov 17 22:19:15 2020 +0100
sw_fieldmarkhide: replace IsHideRedlines() with HasMergedParas()
... in wsfrm.cxx
Change-Id: Iaa552f2527d47f475165a3f9da073052fc76ac51
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105983
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index ae9242cbd13e..438eaaef79fd 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4322,7 +4322,7 @@ static void UnHideRedlines(SwRootFrame & rLayout,
auto eMode(sw::FrameMode::Existing);
for (SwTextFrame * pFrame : frames)
{
- if (rLayout.IsHideRedlines())
+ if (rLayout.HasMergedParas())
{
assert(!pFrame->GetMergedPara() ||
!rNode.IsCreateFrameWhenHidingRedlines());
@@ -4435,7 +4435,7 @@ static void UnHideRedlines(SwRootFrame & rLayout,
}
if (!rNode.IsCreateFrameWhenHidingRedlines())
{
- if (rLayout.IsHideRedlines())
+ if (rLayout.HasMergedParas())
{
if (rNode.IsContentNode())
{
@@ -4548,14 +4548,14 @@ static void UnHide(SwRootFrame & rLayout)
std::set<sal_uLong> skippedFlys;
UnHideRedlinesExtras(rLayout, rNodes, rNodes.GetEndOfAutotext(),
// when un-hiding, delay all fly frame creation to AppendAllObjs below
- rLayout.IsHideRedlines() ? &skippedFlys : nullptr);
+ rLayout.HasMergedParas() ? &skippedFlys : nullptr);
// Footnotes are created automatically (after invalidation etc.) by
// ConnectFootnote(), but need to be deleted manually. Footnotes do not
// occur in flys or headers/footers.
UnHideRedlinesExtras(rLayout, rNodes, rNodes.GetEndOfInserts(), nullptr);
UnHideRedlines(rLayout, rNodes, rNodes.GetEndOfContent(), nullptr);
- if (!rLayout.IsHideRedlines())
+ if (!rLayout.HasMergedParas())
{ // create all previously hidden flys at once:
// * Flys on first node of pre-existing merged frames that are hidden
// (in delete redline), to be added to the existing frame
@@ -4608,7 +4608,7 @@ static void UnHide(SwRootFrame & rLayout)
// update SwPostItMgr / notes in the margin
// note: as long as all shells share layout, broadcast to all shells!
- rDoc.GetDocShell()->Broadcast( SwFormatFieldHint(nullptr, rLayout.IsHideRedlines()
+ rDoc.GetDocShell()->Broadcast( SwFormatFieldHint(nullptr, rLayout.HasMergedParas()
? SwFormatFieldHintWhich::REMOVED
: SwFormatFieldHintWhich::INSERTED) );
More information about the Libreoffice-commits
mailing list