sw/inc/SwNodeNum.hxx | 7 + sw/inc/list.hxx | 1 sw/inc/ndtxt.hxx | 19 +--- sw/source/core/SwNumberTree/SwNodeNum.cxx | 23 ++-- sw/source/core/doc/list.cxx | 53 ++++++++--- sw/source/core/inc/txtfrm.hxx | 4 sw/source/core/layout/wsfrm.cxx | 5 + sw/source/core/text/EnhancedPDFExportHelper.cxx | 4 sw/source/core/text/redlnitr.cxx | 18 +++ sw/source/core/text/txtfld.cxx | 5 - sw/source/core/text/txtfrm.cxx | 12 +- sw/source/core/txtnode/ndtxt.cxx | 113 ++++++++++++++++++------ sw/source/uibase/utlui/content.cxx | 2 13 files changed, 191 insertions(+), 75 deletions(-)
New commits: commit fa7b0497979d6de60e92ccb56b94d27f1c69a5c3 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Oct 19 16:06:08 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Oct 19 16:59:57 2018 +0200 sw_redlinehide_3: invalidate numbered text nodes on Show/Hide Call the same function as SwNodeNum::NotifyNode(). Change-Id: If2edc5fb9364e97715d4750f3a45c3c918edfebf diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index 7aff243c691a..a8486ef619ad 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -4344,6 +4344,11 @@ static void UnHideRedlines(SwRootFrame & rLayout, } pFrame->Broadcast(SfxHint()); // notify SwAccessibleParagraph } + // all nodes, not just merged ones! it may be in the same list as + if (rTextNode.IsNumbered()) // a preceding merged one... + { // notify frames so they reformat numbering portions + rTextNode.NumRuleChgd(); + } } if (!rNode.IsCreateFrameWhenHidingRedlines()) { commit 8db3d69042ae34e05be168644f8bf9babd380abf Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Oct 19 15:59:53 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Oct 19 16:59:57 2018 +0200 sw_redlinehide_3: use the second list number in the text formatting Change-Id: Ibe2afae869b1999772fa6132e35a1e951fffddd2 diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx index d171a5fbef80..a666da304538 100644 --- a/sw/source/core/text/EnhancedPDFExportHelper.cxx +++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx @@ -419,7 +419,7 @@ void SwTaggedPDFHelper::BeginTag( vcl::PDFWriter::StructElement eType, const OUS { const SwTextFrame& rTextFrame = static_cast<const SwTextFrame&>(mpNumInfo->mrFrame); SwTextNode const*const pTextNd = rTextFrame.GetTextNodeForParaProps(); - const SwNodeNum* pNodeNum = pTextNd->GetNum(); + const SwNodeNum* pNodeNum = pTextNd->GetNum(rTextFrame.getRootFrame()); if ( vcl::PDFWriter::List == eType ) { @@ -838,7 +838,7 @@ void SwTaggedPDFHelper::BeginNumberedListStructureElements() const SwTextNode *const pTextNd = rTextFrame.GetTextNodeForParaProps(); const SwNumRule* pNumRule = pTextNd->GetNumRule(); - const SwNodeNum* pNodeNum = pTextNd->GetNum(); + const SwNodeNum* pNodeNum = pTextNd->GetNum(rTextFrame.getRootFrame()); const bool bNumbered = !pTextNd->IsOutline() && pNodeNum && pNodeNum->GetParent() && pNumRule; diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx index 196b11b84cf9..e7fd1223fe95 100644 --- a/sw/source/core/text/txtfld.cxx +++ b/sw/source/core/text/txtfld.cxx @@ -472,6 +472,9 @@ SwNumberPortion *SwTextFormatter::NewNumberPortion( SwTextFormatInfo &rInf ) con return nullptr; SwNumberPortion *pRet = nullptr; + // sw_redlinehide: at this point it's certain that pTextNd is the node with + // the numbering of the frame; only the actual number-vector (GetNumString) + // depends on the hide-mode in the layout so other calls don't need to care const SwTextNode *const pTextNd = GetTextFrame()->GetTextNodeForParaProps(); const SwNumRule* pNumRule = pTextNd->GetNumRule(); @@ -572,7 +575,7 @@ SwNumberPortion *SwTextFormatter::NewNumberPortion( SwTextFormatInfo &rInf ) con } else { - OUString aText( pTextNd->GetNumString() ); + OUString aText( pTextNd->GetNumString(true, MAXLEVEL, m_pFrame->getRootFrame()) ); if ( !aText.isEmpty() ) { aText += pTextNd->GetLabelFollowedBy(); diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 91b1024aa9d8..614fa1a9b8bc 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -1868,7 +1868,7 @@ bool SwContentTree::FillTransferData( TransferDataContainer& rTransfer, if( pTextNd && pOutlRule && pTextNd->IsNumbered()) { SwNumberTree::tNumberVector aNumVector = - pTextNd->GetNumberVector(); + pTextNd->GetNumberVector(pWrtShell->GetLayout()); for( int nLevel = 0; nLevel <= pTextNd->GetActualListLevel(); nLevel++ ) commit 265ce9585e7c369238b6cae3af38eb818bef1f49 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Oct 19 15:55:42 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Oct 19 16:59:57 2018 +0200 sw_redlinehide_3: have SwTextFrame ensure that list node is ... ... always the same as pParaPropsNode. Change-Id: I1fb225d147ec3558615ad16ec49f873db7f1628f diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index 93c1e9a6b7a1..9e720cbb3260 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -933,14 +933,14 @@ struct MergedPara /// const_casts it and modifies it (also, Update will modify it) OUString mergedText; /// most paragraph properties are taken from the first non-empty node - SwTextNode const* pParaPropsNode; + SwTextNode * pParaPropsNode; /// except break attributes, those are taken from the first node SwTextNode *const pFirstNode; /// mainly for sanity checks SwTextNode const* pLastNode; MergedPara(SwTextFrame & rFrame, std::vector<Extent>&& rExtents, OUString const& rText, - SwTextNode const*const pProps, SwTextNode *const pFirst, + SwTextNode *const pProps, SwTextNode *const pFirst, SwTextNode const*const pLast) : listener(rFrame), extents(std::move(rExtents)), mergedText(rText) , pParaPropsNode(pProps), pFirstNode(pFirst), pLastNode(pLast) diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index a6491e618e47..81aac678b427 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -833,7 +833,9 @@ static TextFrameIndex UpdateMergedParaForInsert(MergedPara & rMerged, nInserted = nLen; if (rNode.GetIndex() < rMerged.pParaPropsNode->GetIndex()) { // text inserted before current para-props node - rMerged.pParaPropsNode = &rNode; + rMerged.pParaPropsNode->RemoveFromListRLHidden(); + rMerged.pParaPropsNode = &const_cast<SwTextNode&>(rNode); + rMerged.pParaPropsNode->AddToListRLHidden(); } } rMerged.mergedText = text.makeStringAndClear(); @@ -959,9 +961,11 @@ TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged, { // all visible text from node was erased if (rMerged.pParaPropsNode == &rNode) { + rMerged.pParaPropsNode->RemoveFromListRLHidden(); rMerged.pParaPropsNode = rMerged.extents.empty() ? rMerged.pFirstNode : rMerged.extents.front().pNode; + rMerged.pParaPropsNode->AddToListRLHidden(); } // NOPE must listen on all non-hidden nodes; particularly on pLastNode rMerged.listener.EndListening(&const_cast<SwTextNode&>(rNode)); } commit 5c28522b91008540f38506046d545da97b7f069c Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Oct 19 15:51:30 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Oct 19 16:59:57 2018 +0200 sw_redlinehide_3: CheckParaRedlineMerge maintains second list tree ... by calling AddToListRLHidden/RemoveFromListRLHidden. Do this here because it has all the necessary information. Change-Id: Iac2640b7493267b187e66b1d464c79fe90642afe diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx index ccfc4ac803db..598c0bc321da 100644 --- a/sw/source/core/text/redlnitr.cxx +++ b/sw/source/core/text/redlnitr.cxx @@ -62,7 +62,7 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, std::vector<SwSectionNode *> sections; std::vector<sw::Extent> extents; OUStringBuffer mergedText; - SwTextNode const* pParaPropsNode(nullptr); + SwTextNode * pParaPropsNode(nullptr); SwTextNode * pNode(&rTextNode); sal_Int32 nLastEnd(0); for (auto i = rIDRA.GetRedlinePos(rTextNode, USHRT_MAX); @@ -180,6 +180,10 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, } if (!bHaveRedlines) { + if (rTextNode.IsInList() && !rTextNode.GetNum(rFrame.getRootFrame())) + { + rTextNode.AddToListRLHidden(); // try to add it... + } return nullptr; } if (nLastEnd != pNode->Len()) @@ -197,6 +201,18 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode, assert(!mergedText.isEmpty()); pParaPropsNode = extents.begin()->pNode; // para props from first node that isn't empty } + // keep lists up to date with visible nodes + if (pParaPropsNode->IsInList() && !pParaPropsNode->GetNum(rFrame.getRootFrame())) + { + pParaPropsNode->AddToListRLHidden(); // try to add it... + } + for (auto const pTextNode : nodes) + { + if (pTextNode != pParaPropsNode) + { + pTextNode->RemoveFromListRLHidden(); + } + } if (eMode == FrameMode::Existing) { // remove existing footnote frames for first node; diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index 74d6253381d4..a6491e618e47 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -611,8 +611,7 @@ SwTextFrame::SwTextFrame(SwTextNode * const pNode, SwFrame* pSib ) , mnFootnoteLine( 0 ) , mnHeightOfLastLine( 0 ) , mnAdditionalFirstLineOffset( 0 ) - // note: this may change this->pRegisteredIn to m_pMergedPara->listeners - , m_pMergedPara(CheckParaRedlineMerge(*this, *pNode, sw::FrameMode::New)) // ensure it is inited + , m_pMergedPara(nullptr) , mnOffset( 0 ) , mnCacheIndex( USHRT_MAX ) , mbLocked( false ) @@ -629,6 +628,9 @@ SwTextFrame::SwTextFrame(SwTextNode * const pNode, SwFrame* pSib ) , mbFollowFormatAllowed( true ) { mnFrameType = SwFrameType::Txt; + // note: this may call SwClientNotify if it's in a list so do it last + // note: this may change this->pRegisteredIn to m_pMergedPara->listeners + m_pMergedPara = CheckParaRedlineMerge(*this, *pNode, sw::FrameMode::New); } namespace sw { commit 0d3894eaac20dcda68ca88c3f89e3b6f591ab983 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Oct 19 15:46:27 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Oct 19 16:59:57 2018 +0200 sw_redlinehide_3: apparently a live SwNodeNum always has a parent ... so assert that somewhere. Change-Id: I928c55ffa57ec037e9406618d20b454e11dd80d4 diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 109c9b67f005..215a0c79783b 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -4335,6 +4335,8 @@ void SwTextNode::RemoveFromListRLHidden() bool SwTextNode::IsInList() const { + // it looks like an unconnected Num can't happen, except in the undo-array + assert(!GetNum() || GetNum()->GetParent() || !GetNodes().IsDocNodes()); return GetNum() != nullptr && GetNum()->GetParent() != nullptr; } commit f596201e98afe6ca82a1ada8782fcb3e4195e755 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Oct 19 15:27:09 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Oct 19 16:59:57 2018 +0200 sw_redlinehide_3: add second SwNodeNum to SwTextNode Change-Id: I62ebdb92ee384905bba9ef3865fcdb306775baf2 diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx index d84c3053533c..97450d63a7a6 100644 --- a/sw/inc/ndtxt.hxx +++ b/sw/inc/ndtxt.hxx @@ -92,6 +92,7 @@ class SW_DLLPUBLIC SwTextNode std::unique_ptr<SwpHints> m_pSwpHints; mutable SwNodeNum* mpNodeNum; ///< Numbering for this paragraph. + mutable SwNodeNum* mpNodeNumRLHidden; ///< Numbering for this paragraph (hidden redlines) OUString m_Text; @@ -165,12 +166,6 @@ class SW_DLLPUBLIC SwTextNode SAL_DLLPRIVATE void InitSwParaStatistics( bool bNew ); - /** create number for this text node, if not already existing - - @return number of this node - */ - SwNodeNum* CreateNum() const; - inline void TryDeleteSwpHints(); SAL_DLLPRIVATE void impl_FormatToTextAttr(const SfxItemSet& i_rAttrSet); @@ -428,12 +423,9 @@ public: */ SwNumRule *GetNumRule(bool bInParent = true) const; - const SwNodeNum* GetNum() const - { - return mpNodeNum; - } + const SwNodeNum* GetNum(SwRootFrame const* pLayout = nullptr) const; - SwNumberTree::tNumberVector GetNumberVector() const; + SwNumberTree::tNumberVector GetNumberVector(SwRootFrame const* pLayout = nullptr) const; /** Returns if this text node is an outline. @@ -467,7 +459,8 @@ public: MAXLEVEL */ OUString GetNumString( const bool _bInclPrefixAndSuffixStrings = true, - const unsigned int _nRestrictToThisLevel = MAXLEVEL ) const; + const unsigned int _nRestrictToThisLevel = MAXLEVEL, + SwRootFrame const* pLayout = nullptr) const; /** Returns the additional indents of this text node and its numbering. @@ -773,7 +766,9 @@ public: bool IsCountedInList() const; void AddToList(); + void AddToListRLHidden(); void RemoveFromList(); + void RemoveFromListRLHidden(); bool IsInList() const; bool IsFirstOfNumRule() const; diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 98768f0422d0..109c9b67f005 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -201,6 +201,7 @@ SwTextNode *SwNodes::MakeTextNode( const SwNodeIndex & rWhere, SwTextNode::SwTextNode( const SwNodeIndex &rWhere, SwTextFormatColl *pTextColl, const SfxItemSet* pAutoAttr ) : SwContentNode( rWhere, SwNodeType::Text, pTextColl ), mpNodeNum( nullptr ), + mpNodeNumRLHidden(nullptr), m_Text(), m_pParaIdleData_Impl(nullptr), m_bContainsHiddenChars(false), @@ -2872,6 +2873,7 @@ void SwTextNode::NumRuleChgd() if ( pNumRule && pNumRule != GetNum()->GetNumRule() ) { mpNodeNum->ChangeNumRule( *pNumRule ); + mpNodeNumRLHidden->ChangeNumRule( *pNumRule ); } } @@ -3138,14 +3140,15 @@ bool SwTextNode::HasBullet() const // #128041# - introduce parameter <_bInclPrefixAndSuffixStrings> //i53420 added max outline parameter OUString SwTextNode::GetNumString( const bool _bInclPrefixAndSuffixStrings, - const unsigned int _nRestrictToThisLevel ) const + const unsigned int _nRestrictToThisLevel, + SwRootFrame const*const pLayout) const { if (GetDoc()->IsClipBoard() && m_pNumStringCache.get()) { // #i111677# do not expand number strings in clipboard documents return *m_pNumStringCache; } - const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : nullptr; + const SwNumRule* pRule = GetNum(pLayout) ? GetNum(pLayout)->GetNumRule() : nullptr; if ( pRule && IsCountedInList() ) { @@ -3155,7 +3158,7 @@ OUString SwTextNode::GetNumString( const bool _bInclPrefixAndSuffixStrings, (style::NumberingType::NUMBER_NONE == rNumberType.GetNumberingType())) { - return pRule->MakeNumString( GetNum()->GetNumberVector(), + return pRule->MakeNumString( GetNum(pLayout)->GetNumberVector(), _bInclPrefixAndSuffixStrings, false, _nRestrictToThisLevel, @@ -3964,20 +3967,19 @@ SwFormatColl* SwTextNode::ChgFormatColl( SwFormatColl *pNewColl ) return pOldColl; } -SwNodeNum* SwTextNode::CreateNum() const +const SwNodeNum* SwTextNode::GetNum(SwRootFrame const*const pLayout) const { - if ( !mpNodeNum ) - { - mpNodeNum = new SwNodeNum( const_cast<SwTextNode*>(this), false ); - } - return mpNodeNum; + // 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 : mpNodeNum; } -SwNumberTree::tNumberVector SwTextNode::GetNumberVector() const +SwNumberTree::tNumberVector +SwTextNode::GetNumberVector(SwRootFrame const*const pLayout) const { - if ( GetNum() ) + if (SwNodeNum const*const pNum = GetNum(pLayout)) { - return GetNum()->GetNumberVector(); + return pNum->GetNumberVector(); } else { @@ -4083,6 +4085,8 @@ int SwTextNode::GetAttrListLevel() const int SwTextNode::GetActualListLevel() const { + assert(!GetNum() || !mpNodeNumRLHidden || // must be in sync + GetNum()->GetLevelInListTree() == mpNodeNumRLHidden->GetLevelInListTree()); return GetNum() ? GetNum()->GetLevelInListTree() : -1; } @@ -4267,11 +4271,45 @@ void SwTextNode::AddToList() assert(!mpNodeNum); mpNodeNum = new SwNodeNum(this, false); pList->InsertListItem(*mpNodeNum, false, GetAttrListLevel()); + // 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()) + { + if (pFrame->getRootFrame()->IsHideRedlines()) + { + sw::MergedPara const*const pMerged = pFrame->GetMergedPara(); + if (!pMerged || this == pMerged->pParaPropsNode) + { + AddToListRLHidden(); + } + break; // assume it's consistent, need to check only once + } + } + } +} + +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 = new SwNodeNum(this, true); + pList->InsertListItem(*mpNodeNumRLHidden, true, GetAttrListLevel()); } } void SwTextNode::RemoveFromList() { + // sw_redlinehide: ensure it's removed from the other half too! + RemoveFromListRLHidden(); if ( IsInList() ) { SwList::RemoveListItem( *mpNodeNum ); @@ -4282,6 +4320,19 @@ void SwTextNode::RemoveFromList() } } +void SwTextNode::RemoveFromListRLHidden() +{ + if (mpNodeNumRLHidden) // direct access because RemoveFromList doesn't have layout + { + assert(mpNodeNumRLHidden->GetParent() || !GetNodes().IsDocNodes()); + SwList::RemoveListItem(*mpNodeNumRLHidden); + delete mpNodeNumRLHidden; + mpNodeNumRLHidden = nullptr; + + SetWordCountDirty( true ); + } +} + bool SwTextNode::IsInList() const { return GetNum() != nullptr && GetNum()->GetParent() != nullptr; commit 69df472db920aad80f373340bf4e28fec3b174c2 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Oct 19 15:08:01 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Oct 19 16:59:57 2018 +0200 sw_redlinehide_3: add flag to SwNodeNum Disable the NumRule/DocumentListsItemManager manipulations on the second tree; only the "main" tree does that. Change-Id: I0da8ced53f8d55758e3c02fd24b9253bbf603b38 diff --git a/sw/inc/SwNodeNum.hxx b/sw/inc/SwNodeNum.hxx index d9e61b115b55..cb277b7e7880 100644 --- a/sw/inc/SwNodeNum.hxx +++ b/sw/inc/SwNodeNum.hxx @@ -30,7 +30,9 @@ class SW_DLLPUBLIC SwNodeNum : public SwNumberTreeNode { public: - explicit SwNodeNum( SwTextNode* pTextNode ); + explicit SwNodeNum( SwTextNode* pTextNode, bool isHiddenRedlines ); + // note: this is only for creating phantom nodes and root nodes; these + // never have a text node explicit SwNodeNum( SwNumRule* pNumRule ); virtual ~SwNodeNum() override; @@ -79,8 +81,9 @@ protected: // method called at a child after this child has been removed from the list tree virtual void PostRemove() override; private: - SwTextNode * mpTextNode; + SwTextNode *const mpTextNode; SwNumRule * mpNumRule; + bool m_isHiddenRedlines; static void UnregisterMeAndChildrenDueToRootDelete( SwNodeNum& rNodeNum ); diff --git a/sw/source/core/SwNumberTree/SwNodeNum.cxx b/sw/source/core/SwNumberTree/SwNodeNum.cxx index 72d5691e987a..40bf1b2eb0c2 100644 --- a/sw/source/core/SwNumberTree/SwNodeNum.cxx +++ b/sw/source/core/SwNumberTree/SwNodeNum.cxx @@ -27,17 +27,17 @@ #include <IDocumentListItems.hxx> #include <doc.hxx> -SwNodeNum::SwNodeNum( SwTextNode* pTextNode ) - : SwNumberTreeNode(), - mpTextNode( pTextNode ), - mpNumRule( nullptr ) +SwNodeNum::SwNodeNum(SwTextNode* pTextNode, bool const isHiddenRedlines) + : mpTextNode( pTextNode ) + , mpNumRule( nullptr ) + , m_isHiddenRedlines(isHiddenRedlines) { } SwNodeNum::SwNodeNum( SwNumRule* pNumRule ) - : SwNumberTreeNode(), - mpTextNode( nullptr ), - mpNumRule( pNumRule ) + : mpTextNode( nullptr ) + , mpNumRule( pNumRule ) + , m_isHiddenRedlines(false) { } @@ -87,11 +87,12 @@ void SwNodeNum::PreAdd() } OSL_ENSURE( GetNumRule(), "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" ); - if ( GetNumRule() && GetTextNode() ) + if (!m_isHiddenRedlines && GetNumRule() && GetTextNode()) { GetNumRule()->AddTextNode( *(GetTextNode()) ); } + if (!m_isHiddenRedlines) { if ( GetTextNode() && GetTextNode()->GetNodes().IsDocNodes() ) @@ -108,14 +109,14 @@ void SwNodeNum::PostRemove() OSL_ENSURE( GetNumRule(), "<SwNodeNum::PostRemove()> - no list style set at <SwNodeNum> instance" ); - if ( GetTextNode() ) + if (!m_isHiddenRedlines && GetTextNode()) { GetTextNode()->getIDocumentListItems().removeListItem( *this ); } if ( GetNumRule() ) { - if ( GetTextNode() ) + if (!m_isHiddenRedlines && GetTextNode()) { GetNumRule()->RemoveTextNode( *(GetTextNode()) ); } @@ -370,7 +371,7 @@ const SwNodeNum* SwNodeNum::GetPrecedingNodeNumOf( const SwTextNode& rTextNode ) const SwNodeNum* pPrecedingNodeNum( nullptr ); // #i83479# - SwNodeNum aNodeNumForTextNode( const_cast<SwTextNode*>(&rTextNode) ); + SwNodeNum aNodeNumForTextNode( const_cast<SwTextNode*>(&rTextNode), false/*doesn't matter*/ ); pPrecedingNodeNum = dynamic_cast<const SwNodeNum*>( GetRoot() diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 0e539ba2c94e..98768f0422d0 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -3968,7 +3968,7 @@ SwNodeNum* SwTextNode::CreateNum() const { if ( !mpNodeNum ) { - mpNodeNum = new SwNodeNum( const_cast<SwTextNode*>(this) ); + mpNodeNum = new SwNodeNum( const_cast<SwTextNode*>(this), false ); } return mpNodeNum; } @@ -4265,7 +4265,7 @@ void SwTextNode::AddToList() if (pList) { assert(!mpNodeNum); - mpNodeNum = new SwNodeNum(this); + mpNodeNum = new SwNodeNum(this, false); pList->InsertListItem(*mpNodeNum, false, GetAttrListLevel()); } } commit 94ef7c6b02329536470a50f5ad9fca3dbaac3a17 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Oct 19 14:49:12 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Oct 19 16:48:52 2018 +0200 sw_redlinehide_3: add second SwNodeNum tree to SwList ... so it can be used when redlines are hidden in the layout. Change-Id: I6cb2bca2fb8ba3913bbf6633996341b52639fe41 diff --git a/sw/inc/list.hxx b/sw/inc/list.hxx index 1c5bfc7d4478..1cfdad5e0716 100644 --- a/sw/inc/list.hxx +++ b/sw/inc/list.hxx @@ -44,6 +44,7 @@ class SwList void SetDefaultListStyleName(OUString const&); void InsertListItem( SwNodeNum& rNodeNum, + bool isHiddenRedlines, const int nLevel ); static void RemoveListItem( SwNodeNum& rNodeNum ); diff --git a/sw/source/core/doc/list.cxx b/sw/source/core/doc/list.cxx index a3c4e90dcc49..c449c58e97b0 100644 --- a/sw/source/core/doc/list.cxx +++ b/sw/source/core/doc/list.cxx @@ -39,7 +39,7 @@ class SwListImpl const OUString& GetDefaultListStyleName() const { return msDefaultListStyleName;} - void InsertListItem( SwNodeNum& rNodeNum, + void InsertListItem( SwNodeNum& rNodeNum, bool isHiddenRedlines, const int nLevel ); static void RemoveListItem( SwNodeNum& rNodeNum ); @@ -57,7 +57,24 @@ class SwListImpl OUString msDefaultListStyleName; // list trees for certain document ranges - typedef std::pair<std::unique_ptr<SwNodeNum>, std::unique_ptr<SwPaM>> tListTreeForRange; + struct tListTreeForRange + { + /// tree always corresponds to document model + std::unique_ptr<SwNodeNum> pRoot; + /// Tree that is missing those nodes that are merged or hidden + /// by delete redlines; this is only used if there is a layout + /// that has IsHideRedlines() enabled. + /// A second tree is needed because not only are the numbers in + /// the nodes different, the structure of the tree may be different + /// as well, if a high-level node is hidden its children go under + /// the previous node on the same level. + /// The nodes of pRootRLHidden are a subset of the nodes of pRoot. + std::unique_ptr<SwNodeNum> pRootRLHidden; + /// top-level SwNodes section + std::unique_ptr<SwPaM> pSection; + tListTreeForRange(SwNodeNum *const p1, SwNodeNum *const p2, SwPaM *const p3) + : pRoot(p1), pRootRLHidden(p2), pSection(p3) {} + }; typedef std::vector<tListTreeForRange> tListTrees; tListTrees maListTrees; @@ -81,8 +98,9 @@ SwListImpl::SwListImpl( const OUString& sListId, SwPaM aPam( *pNode, *pNode->EndOfSectionNode() ); SwNodeNum* pNumberTreeRootNode = new SwNodeNum( &rDefaultListStyle ); + SwNodeNum* pNumberTreeRootNodeRL = new SwNodeNum( &rDefaultListStyle ); SwPaM* pPam = new SwPaM( *(aPam.Start()), *(aPam.End()) ); - maListTrees.emplace_back(pNumberTreeRootNode, pPam); + maListTrees.emplace_back(pNumberTreeRootNode, pNumberTreeRootNodeRL, pPam); pNode = pNode->EndOfSectionNode(); if (pNode != &rNodes.GetEndOfContent()) @@ -102,12 +120,12 @@ SwListImpl::~SwListImpl() COVERITY_NOEXCEPT_FALSE aNumberTreeIter != maListTrees.end(); ++aNumberTreeIter ) { - SwNodeNum::HandleNumberTreeRootNodeDelete( *((*aNumberTreeIter).first) ); + SwNodeNum::HandleNumberTreeRootNodeDelete(*((*aNumberTreeIter).pRoot)); + SwNodeNum::HandleNumberTreeRootNodeDelete(*((*aNumberTreeIter).pRootRLHidden)); } } - -void SwListImpl::InsertListItem( SwNodeNum& rNodeNum, +void SwListImpl::InsertListItem( SwNodeNum& rNodeNum, bool const isHiddenRedlines, const int nLevel ) { const SwPosition aPosOfNodeNum( rNodeNum.GetPosition() ); @@ -118,15 +136,17 @@ void SwListImpl::InsertListItem( SwNodeNum& rNodeNum, aNumberTreeIter != maListTrees.end(); ++aNumberTreeIter ) { - const SwPosition* pStart = (*aNumberTreeIter).second->Start(); - const SwPosition* pEnd = (*aNumberTreeIter).second->End(); + const SwPosition* pStart = (*aNumberTreeIter).pSection->Start(); + const SwPosition* pEnd = (*aNumberTreeIter).pSection->End(); const SwNodes* pRangeNodes = &(pStart->nNode.GetNode().GetNodes()); if ( pRangeNodes == pNodesOfNodeNum && *pStart <= aPosOfNodeNum && aPosOfNodeNum <= *pEnd) { - (*aNumberTreeIter).first->AddChild( &rNodeNum, nLevel ); - + auto const& pRoot(isHiddenRedlines + ? (*aNumberTreeIter).pRootRLHidden + : (*aNumberTreeIter).pRoot); + pRoot->AddChild(&rNodeNum, nLevel); break; } } @@ -144,7 +164,8 @@ void SwListImpl::InvalidateListTree() aNumberTreeIter != maListTrees.end(); ++aNumberTreeIter ) { - (*aNumberTreeIter).first->InvalidateTree(); + (*aNumberTreeIter).pRoot->InvalidateTree(); + (*aNumberTreeIter).pRootRLHidden->InvalidateTree(); } } @@ -155,7 +176,8 @@ void SwListImpl::ValidateListTree() aNumberTreeIter != maListTrees.end(); ++aNumberTreeIter ) { - (*aNumberTreeIter).first->NotifyInvalidChildren(); + (*aNumberTreeIter).pRoot->NotifyInvalidChildren(); + (*aNumberTreeIter).pRootRLHidden->NotifyInvalidChildren(); } } @@ -202,7 +224,8 @@ void SwListImpl::NotifyItemsOnListLevel( const int nLevel ) aNumberTreeIter != maListTrees.end(); ++aNumberTreeIter ) { - (*aNumberTreeIter).first->NotifyNodesOnListLevel( nLevel ); + (*aNumberTreeIter).pRoot->NotifyNodesOnListLevel( nLevel ); + (*aNumberTreeIter).pRootRLHidden->NotifyNodesOnListLevel( nLevel ); } } @@ -232,10 +255,10 @@ void SwList::SetDefaultListStyleName(OUString const& rNew) mpListImpl->msDefaultListStyleName = rNew; } -void SwList::InsertListItem( SwNodeNum& rNodeNum, +void SwList::InsertListItem( SwNodeNum& rNodeNum, bool const isHiddenRedlines, const int nLevel ) { - mpListImpl->InsertListItem( rNodeNum, nLevel ); + mpListImpl->InsertListItem( rNodeNum, isHiddenRedlines, nLevel ); } void SwList::RemoveListItem( SwNodeNum& rNodeNum ) diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index e0e6d4223840..0e539ba2c94e 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -4230,33 +4230,43 @@ bool SwTextNode::IsCountedInList() const return aIsCountedInListItem.GetValue(); } -void SwTextNode::AddToList() +static SwList * FindList(SwTextNode *const pNode) { - if ( IsInList() ) - { - OSL_FAIL( "<SwTextNode::AddToList()> - the text node is already added to a list. Serious defect" ); - return; - } - - const OUString sListId = GetListId(); + const OUString sListId = pNode->GetListId(); if (!sListId.isEmpty()) { - SwList* pList = GetDoc()->getIDocumentListsAccess().getListByName( sListId ); + auto & rIDLA(pNode->GetDoc()->getIDocumentListsAccess()); + SwList* pList = rIDLA.getListByName( sListId ); if ( pList == nullptr ) { // Create corresponding list. - SwNumRule* pNumRule = GetNumRule(); + SwNumRule* pNumRule = pNode->GetNumRule(); if ( pNumRule ) { - pList = GetDoc()->getIDocumentListsAccess().createList( sListId, GetNumRule()->GetName() ); + pList = rIDLA.createList(sListId, pNode->GetNumRule()->GetName()); } } OSL_ENSURE( pList != nullptr, "<SwTextNode::AddToList()> - no list for given list id. Serious defect" ); - if ( pList ) - { - pList->InsertListItem( *CreateNum(), GetAttrListLevel() ); - } + return pList; + } + return nullptr; +} + +void SwTextNode::AddToList() +{ + if ( IsInList() ) + { + OSL_FAIL( "<SwTextNode::AddToList()> - the text node is already added to a list. Serious defect" ); + return; + } + + SwList *const pList(FindList(this)); + if (pList) + { + assert(!mpNodeNum); + mpNodeNum = new SwNodeNum(this); + pList->InsertListItem(*mpNodeNum, false, GetAttrListLevel()); } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits