summaryrefslogtreecommitdiff
path: root/sw/source/core
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2022-06-23 12:11:22 +0200
committerLászló Németh <nemeth@numbertext.org>2022-06-24 09:16:47 +0200
commit2413f213625253a9c2b1787b3b9fe859d724a9bd (patch)
tree6cbe24f606864f676acdc7059c5c418ad343b9f1 /sw/source/core
parent9e170a35eebbe86e6137510bc8ea34e5a45dbd8d (diff)
tdf#115523 sw_redlinenum: show correct, also original numbering
in Show Changes mode, according to the name "Show Changes" and according to the interoperability requirements. Instead of the fake numbering which counted the deleted list items in Show Changes mode, e.g.: "3. This was the third originally, but now it's the second list item." now show the correct number followed by the original number within braces: "2.[3.] This was the third originally, but now it's the second list item." Note: the tabulators after the longer numbering are replaced with spaces to avoid messy indentation in Show Changes mode. New enum values for the alternative lists: SwListRedlineType::SHOW - the original (fake) numbering in Show Changes mode SwListRedlineType::HIDDEN - the original numbering of Hide Changes mode, and new numbering in Show Changes mode SwListRedlineType::ORIGTEXT - the new numbering of Show Changes mode to show the original numbering of the deleted or inserted list items Follow-up to commit c180c9447256588fe5e7991e06642883574760ae "sw_redlinehide_3: add second SwNodeNum to SwTextNode". Change-Id: Ieaca550561c5d5a7ac5d9defb9c7fa283d6aa674 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136313 Tested-by: Jenkins Reviewed-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'sw/source/core')
-rw-r--r--sw/source/core/doc/list.cxx13
-rw-r--r--sw/source/core/text/txtfld.cxx43
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx86
3 files changed, 111 insertions, 31 deletions
diff --git a/sw/source/core/doc/list.cxx b/sw/source/core/doc/list.cxx
index 7965856519cc..9543e083d711 100644
--- a/sw/source/core/doc/list.cxx
+++ b/sw/source/core/doc/list.cxx
@@ -39,6 +39,7 @@ SwList::SwList( const OUString& sListId,
maListTrees.emplace_back(
std::make_unique<SwNodeNum>( &rDefaultListStyle ),
std::make_unique<SwNodeNum>( &rDefaultListStyle ),
+ std::make_unique<SwNodeNum>( &rDefaultListStyle ),
std::make_unique<SwPaM>( *(aPam.Start()), *(aPam.End()) ));
pNode = pNode->EndOfSectionNode();
@@ -58,6 +59,7 @@ SwList::~SwList() COVERITY_NOEXCEPT_FALSE
{
SwNodeNum::HandleNumberTreeRootNodeDelete(*(rNumberTree.pRoot));
SwNodeNum::HandleNumberTreeRootNodeDelete(*(rNumberTree.pRootRLHidden));
+ SwNodeNum::HandleNumberTreeRootNodeDelete(*(rNumberTree.pRootOrigText));
}
}
@@ -73,7 +75,7 @@ bool SwList::HasNodes() const
return false;
}
-void SwList::InsertListItem(SwNodeNum& rNodeNum, bool const isHiddenRedlines,
+void SwList::InsertListItem(SwNodeNum& rNodeNum, SwListRedlineType const eRedline,
const int nLevel, const SwDoc& rDoc)
{
const SwPosition aPosOfNodeNum( rNodeNum.GetPosition() );
@@ -88,9 +90,11 @@ void SwList::InsertListItem(SwNodeNum& rNodeNum, bool const isHiddenRedlines,
if ( pRangeNodes == pNodesOfNodeNum &&
*pStart <= aPosOfNodeNum && aPosOfNodeNum <= *pEnd)
{
- auto const& pRoot(isHiddenRedlines
+ auto const& pRoot(SwListRedlineType::HIDDEN == eRedline
? rNumberTree.pRootRLHidden
- : rNumberTree.pRoot);
+ : SwListRedlineType::SHOW == eRedline
+ ? rNumberTree.pRoot
+ : rNumberTree.pRootOrigText);
pRoot->AddChild(&rNodeNum, nLevel, rDoc);
break;
}
@@ -108,6 +112,7 @@ void SwList::InvalidateListTree()
{
rNumberTree.pRoot->InvalidateTree();
rNumberTree.pRootRLHidden->InvalidateTree();
+ rNumberTree.pRootOrigText->InvalidateTree();
}
}
@@ -117,6 +122,7 @@ void SwList::ValidateListTree(const SwDoc& rDoc)
{
rNumberTree.pRoot->NotifyInvalidChildren(rDoc);
rNumberTree.pRootRLHidden->NotifyInvalidChildren(rDoc);
+ rNumberTree.pRootOrigText->NotifyInvalidChildren(rDoc);
}
}
@@ -162,6 +168,7 @@ void SwList::NotifyItemsOnListLevel( const int nLevel )
{
rNumberTree.pRoot->NotifyNodesOnListLevel( nLevel );
rNumberTree.pRootRLHidden->NotifyNodesOnListLevel( nLevel );
+ rNumberTree.pRootOrigText->NotifyNodesOnListLevel( nLevel );
}
}
diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx
index 06cb7388378e..f935e8d8ab93 100644
--- a/sw/source/core/text/txtfld.cxx
+++ b/sw/source/core/text/txtfld.cxx
@@ -563,15 +563,15 @@ static const SwRangeRedline* lcl_GetRedlineAtNodeInsertionOrDeletion( const SwTe
return nullptr;
}
-static void lcl_setRedlineAttr( SwTextFormatInfo &rInf, const SwTextNode& rTextNode, const std::unique_ptr<SwFont>& pNumFnt )
+static bool lcl_setRedlineAttr( SwTextFormatInfo &rInf, const SwTextNode& rTextNode, const std::unique_ptr<SwFont>& pNumFnt )
{
if ( rInf.GetVsh()->GetLayout()->IsHideRedlines() )
- return;
+ return false;
bool bIsMoved;
const SwRangeRedline* pRedlineNum = lcl_GetRedlineAtNodeInsertionOrDeletion( rTextNode, bIsMoved );
if (!pRedlineNum)
- return;
+ return false;
// moved text: dark green with double underline or strikethrough
if ( bIsMoved )
@@ -581,7 +581,7 @@ static void lcl_setRedlineAttr( SwTextFormatInfo &rInf, const SwTextNode& rTextN
pNumFnt->SetStrikeout(STRIKEOUT_DOUBLE);
else
pNumFnt->SetUnderline(LINESTYLE_DOUBLE);
- return;
+ return true;
}
SwAttrPool& rPool = rInf.GetVsh()->GetDoc()->GetAttrPool();
@@ -602,6 +602,8 @@ static void lcl_setRedlineAttr( SwTextFormatInfo &rInf, const SwTextNode& rTextN
pNumFnt->SetUnderline(pItem->GetLineStyle());
if (const SvxCrossedOutItem* pItem = aSet.GetItemIfSet(RES_CHRATR_CROSSEDOUT))
pNumFnt->SetStrikeout( pItem->GetStrikeout() );
+
+ return true;
}
SwNumberPortion *SwTextFormatter::NewNumberPortion( SwTextFormatInfo &rInf ) const
@@ -730,11 +732,35 @@ SwNumberPortion *SwTextFormatter::NewNumberPortion( SwTextFormatInfo &rInf ) con
}
else
{
- OUString aText( pTextNd->GetNumString(true, MAXLEVEL, m_pFrame->getRootFrame()) );
- if ( !aText.isEmpty() )
+ // Show Changes mode shows the actual numbering (SwListRedlineType::HIDDEN) and
+ // the original one (SwListRedlineType::ORIGTEXT) instead of the fake numbering
+ // (SwListRedlineType::SHOW, which counts removed and inserted numbered paragraphs
+ // in a single list)
+ bool bHasHiddenNum = false;
+ OUString aText( pTextNd->GetNumString(true, MAXLEVEL, m_pFrame->getRootFrame(), SwListRedlineType::HIDDEN) );
+ const SwDoc& rDoc = pTextNd->GetDoc();
+ const SwRedlineTable& rTable = rDoc.getIDocumentRedlineAccess().GetRedlineTable();
+ if ( rTable.size() && !rInf.GetVsh()->GetLayout()->IsHideRedlines() )
{
- aText += pTextNd->GetLabelFollowedBy();
+ OUString aHiddenText( pTextNd->GetNumString(true, MAXLEVEL, m_pFrame->getRootFrame(), SwListRedlineType::ORIGTEXT) );
+
+ if ( !aText.isEmpty() || !aHiddenText.isEmpty() )
+ {
+ if (aText != aHiddenText && !aHiddenText.isEmpty())
+ {
+ bHasHiddenNum = true;
+ // show also original number after the actual one enclosed in [ and ],
+ // and replace tabulator with space to avoid messy indentation
+ // resulted by the longer numbering, e.g. "1.[2.]" instead of "1.".
+ aText = aText + "[" + aHiddenText + "]"
+ + pTextNd->GetLabelFollowedBy().replaceAll("\t", " ");
+ }
+ else if (!aText.isEmpty())
+ aText += pTextNd->GetLabelFollowedBy();
+ }
}
+ else if (!aText.isEmpty())
+ aText += pTextNd->GetLabelFollowedBy();
// Not just an optimization ...
// A number portion without text will be assigned a width of 0.
@@ -763,7 +789,8 @@ SwNumberPortion *SwTextFormatter::NewNumberPortion( SwTextFormatInfo &rInf ) con
checkApplyParagraphMarkFormatToNumbering(pNumFnt.get(), rInf, pIDSA, pFormat);
- lcl_setRedlineAttr( rInf, *pTextNd, pNumFnt );
+ if ( !lcl_setRedlineAttr( rInf, *pTextNd, pNumFnt ) && bHasHiddenNum )
+ pNumFnt->SetColor(NON_PRINTING_CHARACTER_COLOR);
// we do not allow a vertical font
pNumFnt->SetVertical( pNumFnt->GetOrientation(), m_pFrame->IsVertical() );
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 691c42e3c900..72cd894e045e 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -72,7 +72,6 @@
#include <SwNodeNum.hxx>
#include <svl/grabbagitem.hxx>
#include <svl/intitem.hxx>
-#include <list.hxx>
#include <sortedobjs.hxx>
#include <calbck.hxx>
#include <attrhint.hxx>
@@ -3160,24 +3159,24 @@ bool SwTextNode::HasBullet() const
//i53420 added max outline parameter
OUString SwTextNode::GetNumString( const bool _bInclPrefixAndSuffixStrings,
const unsigned int _nRestrictToThisLevel,
- SwRootFrame const*const pLayout) const
+ SwRootFrame const*const pLayout, SwListRedlineType eRedline) const
{
if (GetDoc().IsClipBoard() && m_oNumStringCache)
{
// #i111677# do not expand number strings in clipboard documents
return *m_oNumStringCache;
}
- const SwNumRule* pRule = GetNum(pLayout) ? GetNum(pLayout)->GetNumRule() : nullptr;
+ const SwNumRule* pRule = GetNum(pLayout, eRedline) ? GetNum(pLayout, eRedline)->GetNumRule() : nullptr;
if ( pRule &&
IsCountedInList() )
{
SvxNumberType const& rNumberType(
- pRule->Get( lcl_BoundListLevel(GetActualListLevel()) ) );
+ pRule->Get( lcl_BoundListLevel(GetActualListLevel(eRedline)) ) );
if (rNumberType.IsTextFormat() ||
(style::NumberingType::NUMBER_NONE == rNumberType.GetNumberingType()))
{
- return pRule->MakeNumString( GetNum(pLayout)->GetNumberVector(),
+ return pRule->MakeNumString( GetNum(pLayout, eRedline)->GetNumberVector(),
_bInclPrefixAndSuffixStrings,
_nRestrictToThisLevel,
nullptr,
@@ -3992,11 +3991,13 @@ SwFormatColl* SwTextNode::ChgFormatColl( SwFormatColl *pNewColl )
return pOldColl;
}
-const SwNodeNum* SwTextNode::GetNum(SwRootFrame const*const pLayout) const
+const SwNodeNum* SwTextNode::GetNum(SwRootFrame const*const pLayout, SwListRedlineType eRedline) const
{
// invariant: it's only in list in Hide mode if it's in list in normal mode
assert(mpNodeNum || !mpNodeNumRLHidden);
- return pLayout && pLayout->IsHideRedlines() ? mpNodeNumRLHidden.get() : mpNodeNum.get();
+ return (pLayout && pLayout->IsHideRedlines()) || SwListRedlineType::HIDDEN == eRedline
+ ? mpNodeNumRLHidden.get()
+ : ( SwListRedlineType::ORIGTEXT == eRedline ? mpNodeNumOrig.get() : mpNodeNum.get() );
}
void SwTextNode::DoNum(std::function<void (SwNodeNum &)> const& rFunc)
@@ -4014,9 +4015,9 @@ void SwTextNode::DoNum(std::function<void (SwNodeNum &)> const& rFunc)
}
SwNumberTree::tNumberVector
-SwTextNode::GetNumberVector(SwRootFrame const*const pLayout) const
+SwTextNode::GetNumberVector(SwRootFrame const*const pLayout, SwListRedlineType eRedline) const
{
- if (SwNodeNum const*const pNum = GetNum(pLayout))
+ if (SwNodeNum const*const pNum = GetNum(pLayout, eRedline))
{
return pNum->GetNumberVector();
}
@@ -4137,11 +4138,13 @@ int SwTextNode::GetAttrListLevel() const
return nAttrListLevel;
}
-int SwTextNode::GetActualListLevel() const
+int SwTextNode::GetActualListLevel(SwListRedlineType eRedline) const
{
- assert(!GetNum() || !mpNodeNumRLHidden || // must be in sync
- GetNum()->GetLevelInListTree() == mpNodeNumRLHidden->GetLevelInListTree());
- return GetNum() ? GetNum()->GetLevelInListTree() : -1;
+ assert(SwListRedlineType::SHOW != eRedline ||
+ !GetNum(nullptr, SwListRedlineType::SHOW) || !mpNodeNumRLHidden || // must be in sync
+ GetNum(nullptr, SwListRedlineType::SHOW)->GetLevelInListTree() ==
+ mpNodeNumRLHidden->GetLevelInListTree());
+ return GetNum(nullptr, eRedline) ? GetNum(nullptr, eRedline)->GetLevelInListTree() : -1;
}
void SwTextNode::SetListRestart( bool bRestart )
@@ -4318,10 +4321,30 @@ void SwTextNode::AddToList()
assert(!mpNodeNum);
mpNodeNum.reset(new SwNodeNum(this, false));
- pList->InsertListItem(*mpNodeNum, false, GetAttrListLevel(), GetDoc());
+ pList->InsertListItem(*mpNodeNum, SwListRedlineType::SHOW, GetAttrListLevel(), GetDoc());
+
+ // set redline lists
+ bool bRecordChanges = GetDoc().GetDocShell() && GetDoc().GetDocShell()->IsChangeRecording();
+ if (!bRecordChanges || GetDoc().IsInXMLImport() || GetDoc().IsInWriterfilterImport() )
+ {
+ const SwRedlineTable& rRedTable = GetDoc().getIDocumentRedlineAccess().GetRedlineTable();
+ SwRedlineTable::size_type nRedlPos = GetDoc().getIDocumentRedlineAccess().GetRedlinePos(*this, RedlineType::Insert);
+ // paragraph start is not in a tracked insertion
+ if ( SwRedlineTable::npos == nRedlPos || GetIndex() <= rRedTable[nRedlPos]->Start()->nNode.GetNode().GetIndex() )
+ {
+ AddToListOrig();
+
+ SwRedlineTable::size_type nRedlPosDel = GetDoc().getIDocumentRedlineAccess().GetRedlinePos(*this, RedlineType::Delete);
+ if ( SwRedlineTable::npos == nRedlPosDel )
+ AddToListRLHidden();
+ }
+ }
+ else if ( bRecordChanges )
+ AddToListRLHidden();
+
// iterate all frames & if there's one with hidden layout...
SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> iter(*this);
- for (SwTextFrame* pFrame = iter.First(); pFrame; pFrame = iter.Next())
+ for (SwTextFrame* pFrame = iter.First(); pFrame && !mpNodeNumRLHidden; pFrame = iter.Next())
{
if (pFrame->getRootFrame()->IsHideRedlines())
{
@@ -4337,18 +4360,28 @@ void SwTextNode::AddToList()
void SwTextNode::AddToListRLHidden()
{
if (mpNodeNumRLHidden)
- {
- assert(false);
- OSL_FAIL( "<SwTextNode::AddToListRLHidden()> - the text node is already added to a list. Serious defect" );
return;
- }
SwList *const pList(FindList(this));
if (pList)
{
assert(!mpNodeNumRLHidden);
mpNodeNumRLHidden.reset(new SwNodeNum(this, true));
- pList->InsertListItem(*mpNodeNumRLHidden, true, GetAttrListLevel(), GetDoc());
+ pList->InsertListItem(*mpNodeNumRLHidden, SwListRedlineType::HIDDEN, GetAttrListLevel(), GetDoc());
+ }
+}
+
+void SwTextNode::AddToListOrig()
+{
+ if (mpNodeNumOrig)
+ return;
+
+ SwList *const pList(FindList(this));
+ if (pList)
+ {
+ assert(!mpNodeNumOrig);
+ mpNodeNumOrig.reset(new SwNodeNum(this, true));
+ pList->InsertListItem(*mpNodeNumOrig, SwListRedlineType::ORIGTEXT, GetAttrListLevel(), GetDoc());
}
}
@@ -4356,6 +4389,7 @@ void SwTextNode::RemoveFromList()
{
// sw_redlinehide: ensure it's removed from the other half too!
RemoveFromListRLHidden();
+ RemoveFromListOrig();
if ( IsInList() )
{
SwList::RemoveListItem(*mpNodeNum, GetDoc());
@@ -4377,6 +4411,18 @@ void SwTextNode::RemoveFromListRLHidden()
}
}
+void SwTextNode::RemoveFromListOrig()
+{
+ if (mpNodeNumOrig) // direct access because RemoveFromList doesn't have layout
+ {
+ assert(mpNodeNumOrig->GetParent() || !GetNodes().IsDocNodes());
+ SwList::RemoveListItem(*mpNodeNumOrig, GetDoc());
+ mpNodeNumOrig.reset();
+
+ SetWordCountDirty( true );
+ }
+}
+
bool SwTextNode::IsInList() const
{
return GetNum() != nullptr && GetNum()->GetParent() != nullptr;