diff --git a/sw/inc/redline.hxx b/sw/inc/redline.hxx index 1ad8c456b56c..f2d6c31a40ac 100644 --- a/sw/inc/redline.hxx +++ b/sw/inc/redline.hxx @@ -338,7 +338,7 @@ class SW_DLLPUBLIC SwRedlineHint final : public SfxHint namespace sw { -std::vector GetAllValidRanges(std::unique_ptr p); +std::vector> GetAllValidRanges(std::unique_ptr p); } // namespace sw diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index ec52d3ec1221..677ae7f0b8fd 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -4094,12 +4094,12 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl(SwPaM & rPam return false; // do not add empty redlines } - std::vector redlines; + std::vector> redlines; { auto pRedline(std::make_unique(RedlineType::Delete, rPam)); if (pRedline->HasValidRange()) { - redlines.push_back(pRedline.release()); + redlines.push_back(std::move(pRedline)); } else // sigh ... why is such a selection even possible... { // split it up so we get one SwUndoRedlineDelete per inserted RL @@ -4160,7 +4160,7 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl(SwPaM & rPam m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags( RedlineFlags::On | RedlineFlags::ShowInsert | RedlineFlags::ShowDelete); - for (SwRangeRedline * pRedline : redlines) + for (std::unique_ptr & pRedline : redlines) { assert(pRedline->HasValidRange()); undos.emplace_back(std::make_unique( @@ -4195,14 +4195,14 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl(SwPaM & rPam } } - for (SwRangeRedline *const pRedline : redlines) + for (std::unique_ptr & pRedline : redlines) { // note: 1. the pRedline can still be merged & deleted // 2. the impl. can even DeleteAndJoin the range => no plain PaM std::shared_ptr const pCursor(m_rDoc.CreateUnoCursor(*pRedline->GetMark())); pCursor->SetMark(); *pCursor->GetPoint() = *pRedline->GetPoint(); - m_rDoc.getIDocumentRedlineAccess().AppendRedline(pRedline, true); + m_rDoc.getIDocumentRedlineAccess().AppendRedline(pRedline.release(), true); // sw_redlinehide: 2 reasons why this is needed: // 1. it's the first redline in node => RedlineDelText was sent but ignored // 2. redline spans multiple nodes => must merge text frames diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx index 68225e0741b7..cfd77733e331 100644 --- a/sw/source/core/doc/docredln.cxx +++ b/sw/source/core/doc/docredln.cxx @@ -477,9 +477,9 @@ bool SwRedlineTable::Insert(SwRangeRedline*& p, size_type& rP) namespace sw { -std::vector GetAllValidRanges(std::unique_ptr p) +std::vector> GetAllValidRanges(std::unique_ptr p) { - std::vector ret; + std::vector> ret; // Create valid "sub-ranges" from the Selection auto [pStt, pEnd] = p->StartEnd(); // SwPosition* SwPosition aNewStt( *pStt ); @@ -493,91 +493,90 @@ std::vector GetAllValidRanges(std::unique_ptr p aNewStt.Assign(rNds.GetEndOfContent()); } - SwRangeRedline* pNew = nullptr; - if( aNewStt < *pEnd ) - do { - if( !pNew ) - pNew = new SwRangeRedline( p->GetRedlineData(), aNewStt ); - else + if( aNewStt >= *pEnd ) + return ret; + + std::unique_ptr pNew; + do { + if( !pNew ) + pNew.reset(new SwRangeRedline( p->GetRedlineData(), aNewStt )); + else + { + pNew->DeleteMark(); + *pNew->GetPoint() = aNewStt; + } + + pNew->SetMark(); + GoEndSection( pNew->GetPoint() ); + // i60396: If the redlines starts before a table but the table is the last member + // of the section, the GoEndSection will end inside the table. + // This will result in an incorrect redline, so we've to go back + SwNode* pTab = pNew->GetPoint()->GetNode().StartOfSectionNode()->FindTableNode(); + // We end in a table when pTab != 0 + if( pTab && !pNew->GetMark()->GetNode().StartOfSectionNode()->FindTableNode() ) + { // but our Mark was outside the table => Correction + do { - pNew->DeleteMark(); + // We want to be before the table + pNew->GetPoint()->Assign(*pTab); + pC = GoPreviousPos( pNew->GetPoint(), false ); // here we are. + if( pC ) + pNew->GetPoint()->SetContent( 0 ); + pTab = pNew->GetPoint()->GetNode().StartOfSectionNode()->FindTableNode(); + } while( pTab ); // If there is another table we have to repeat our step backwards + } + + if( *pNew->GetPoint() > *pEnd ) + { + pC = nullptr; + if( aNewStt.GetNode() != pEnd->GetNode() ) + do { + SwNode& rCurNd = aNewStt.GetNode(); + if( rCurNd.IsStartNode() ) + { + if( rCurNd.EndOfSectionIndex() < pEnd->GetNodeIndex() ) + aNewStt.Assign( *rCurNd.EndOfSectionNode() ); + else + break; + } + else if( rCurNd.IsContentNode() ) + pC = rCurNd.GetContentNode(); + aNewStt.Adjust(SwNodeOffset(1)); + } while( aNewStt.GetNodeIndex() < pEnd->GetNodeIndex() ); + + if( aNewStt.GetNode() == pEnd->GetNode() ) + aNewStt.SetContent(pEnd->GetContentIndex()); + else if( pC ) + { + aNewStt.Assign(*pC, pC->Len() ); + } + + if( aNewStt <= *pEnd ) *pNew->GetPoint() = aNewStt; - } - - pNew->SetMark(); - GoEndSection( pNew->GetPoint() ); - // i60396: If the redlines starts before a table but the table is the last member - // of the section, the GoEndSection will end inside the table. - // This will result in an incorrect redline, so we've to go back - SwNode* pTab = pNew->GetPoint()->GetNode().StartOfSectionNode()->FindTableNode(); - // We end in a table when pTab != 0 - if( pTab && !pNew->GetMark()->GetNode().StartOfSectionNode()->FindTableNode() ) - { // but our Mark was outside the table => Correction - do - { - // We want to be before the table - pNew->GetPoint()->Assign(*pTab); - pC = GoPreviousPos( pNew->GetPoint(), false ); // here we are. - if( pC ) - pNew->GetPoint()->SetContent( 0 ); - pTab = pNew->GetPoint()->GetNode().StartOfSectionNode()->FindTableNode(); - } while( pTab ); // If there is another table we have to repeat our step backwards - } - - if( *pNew->GetPoint() > *pEnd ) - { - pC = nullptr; - if( aNewStt.GetNode() != pEnd->GetNode() ) - do { - SwNode& rCurNd = aNewStt.GetNode(); - if( rCurNd.IsStartNode() ) - { - if( rCurNd.EndOfSectionIndex() < pEnd->GetNodeIndex() ) - aNewStt.Assign( *rCurNd.EndOfSectionNode() ); - else - break; - } - else if( rCurNd.IsContentNode() ) - pC = rCurNd.GetContentNode(); - aNewStt.Adjust(SwNodeOffset(1)); - } while( aNewStt.GetNodeIndex() < pEnd->GetNodeIndex() ); - - if( aNewStt.GetNode() == pEnd->GetNode() ) - aNewStt.SetContent(pEnd->GetContentIndex()); - else if( pC ) - { - aNewStt.Assign(*pC, pC->Len() ); - } - - if( aNewStt <= *pEnd ) - *pNew->GetPoint() = aNewStt; - } - else - aNewStt = *pNew->GetPoint(); + } + else + aNewStt = *pNew->GetPoint(); #if OSL_DEBUG_LEVEL > 0 - CheckPosition( pNew->GetPoint(), pNew->GetMark() ); + CheckPosition( pNew->GetPoint(), pNew->GetMark() ); #endif - if( *pNew->GetPoint() != *pNew->GetMark() && - pNew->HasValidRange()) - { - ret.push_back(pNew); - pNew = nullptr; - } + if( *pNew->GetPoint() != *pNew->GetMark() && + pNew->HasValidRange()) + { + ret.push_back(std::move(pNew)); + } - if( aNewStt >= *pEnd ) - break; - pC = rNds.GoNext( &aNewStt.nNode ); - if( !pC ) - break; + if( aNewStt >= *pEnd ) + break; + pC = rNds.GoNext( &aNewStt.nNode ); + if( !pC ) + break; - aNewStt.nContent.Assign( pC, 0 ); + aNewStt.nContent.Assign( pC, 0 ); - } while( aNewStt < *pEnd ); + } while( aNewStt < *pEnd ); - delete pNew; - p.reset(); return ret; } @@ -586,15 +585,16 @@ std::vector GetAllValidRanges(std::unique_ptr p bool SwRedlineTable::InsertWithValidRanges(SwRangeRedline*& p, size_type* pInsPos) { bool bAnyIns = false; - std::vector const redlines( + std::vector> redlines( GetAllValidRanges(std::unique_ptr(p))); - for (SwRangeRedline * pRedline : redlines) + for (std::unique_ptr & pRedline : redlines) { assert(pRedline->HasValidRange()); size_type nInsPos; - if (Insert(pRedline, nInsPos)) + auto pTmpRedline = pRedline.release(); + if (Insert(pTmpRedline, nInsPos)) { - pRedline->CallDisplayFunc(nInsPos); + pTmpRedline->CallDisplayFunc(nInsPos); bAnyIns = true; if (pInsPos && *pInsPos < nInsPos) {