sw/inc/IDocumentContentOperations.hxx | 11 +++ sw/inc/editsh.hxx | 4 - sw/qa/core/uwriter.cxx | 2 sw/source/core/doc/DocumentContentOperationsManager.cxx | 46 ++++++++-------- sw/source/core/docnode/ndsect.cxx | 2 sw/source/core/docnode/ndtbl.cxx | 2 sw/source/core/edit/autofmt.cxx | 4 - sw/source/core/edit/eddel.cxx | 9 +-- sw/source/core/edit/edglbldc.cxx | 2 sw/source/core/edit/editsh.cxx | 4 - sw/source/core/frmedt/fecopy.cxx | 2 sw/source/core/inc/DocumentContentOperationsManager.hxx | 9 +-- sw/source/core/inc/UndoDelete.hxx | 3 + sw/source/core/layout/atrfrm.cxx | 2 sw/source/core/undo/undel.cxx | 21 +++++-- sw/source/core/undo/unins.cxx | 2 sw/source/core/undo/unredln.cxx | 4 - sw/source/core/undo/untbl.cxx | 14 ++-- sw/source/uibase/dochdl/swdtflvr.cxx | 2 sw/source/uibase/lingu/hhcwrp.cxx | 4 - sw/source/uibase/ribbar/inputwin.cxx | 4 - sw/source/uibase/wrtsh/delete.cxx | 26 ++++----- sw/source/uibase/wrtsh/select.cxx | 4 - 23 files changed, 109 insertions(+), 74 deletions(-)
New commits: commit 6bd76edc7ffd82690068618e5b322787228bb5d2 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Tue Jun 7 19:01:24 2022 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Tue Jun 21 23:40:02 2022 +0200 tdf#133957 sw: don't delete flys on Backspace/Delete keys Also fixes: tdf#134007 tdf#138835 tdf#139514 When a character is deleted via the keyboard by Backspace or Delete key, an artificial selection is created in SwWrtShell::DelLeft()/DelRight(). Ideally this should not delete flys that may be anchored to the paragraphs, but unfortunately this may happen if there are only 2 empty paragraphs in the section, because then the artificial selection cannot be distinguished by the SwDoc implementation from a selection from Ctrl+A (Select All), which *should* delete the flys. So introduce a new flag that needs to be passed down multiple layers so that SwUndoDelete can use it to determine if flys should be deleted, and translating it to a flag that had been introduced to preserve flys in ReplaceRange() previously. There are a couple more callers that look like they want to "replace" some text, so guess a bit at where to set this new flag. (note: of course fly anchored *as char* must be deleted via keys.) (regression from commit e75dd1fc992f168f24d66595265a978071cdd277) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135476 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 85376a02348810812d515ee72140dbf56f2b6040) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135517 Reviewed-by: Miklos Vajna <vmik...@collabora.com> (cherry picked from commit 5192cd430e8cab0ed04f8c70c5194397455ac705) Change-Id: Ib4467476b12a12aefbbcb74ab9802f9318cf9aa0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136217 Tested-by: Michael Stahl <michael.st...@allotropia.de> Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx index b6857c346a33..6e6b3c1bad3e 100644 --- a/sw/inc/IDocumentContentOperations.hxx +++ b/sw/inc/IDocumentContentOperations.hxx @@ -69,6 +69,16 @@ namespace o3tl template<> struct typed_flags<SwInsertFlags> : is_typed_flags<SwInsertFlags, 0x07> {}; } +enum class SwDeleteFlags +{ + Default = 0, + ArtificialSelection = (1<<0), ///< keyboard delete, artificial selection, avoid deleting flys +}; +namespace o3tl +{ + template<> struct typed_flags<SwDeleteFlags> : is_typed_flags<SwDeleteFlags, 0x01> {}; +} + /** Text operation/manipulation interface */ class IDocumentContentOperations @@ -130,6 +140,7 @@ public: Needed for hiding of deletion redlines */ virtual bool DeleteAndJoin( SwPaM&, + SwDeleteFlags flags = SwDeleteFlags::Default, const bool bForceJoinNext = false ) = 0; virtual bool MoveRange(SwPaM&, SwPosition&, SwMoveFlags) = 0; diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx index c2224d0575bc..71bf75a3a8b6 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -152,7 +152,7 @@ class SW_DLLPUBLIC SwEditShell : public SwCursorShell that will be used by GetGraphic() and GetGraphicSize(). */ SAL_DLLPRIVATE SwGrfNode *GetGrfNode_() const ; - SAL_DLLPRIVATE void DeleteSel( SwPaM& rPam, bool* pUndo = nullptr ); + SAL_DLLPRIVATE void DeleteSel(SwPaM& rPam, bool isArtificialSelection, bool* pUndo = nullptr); SAL_DLLPRIVATE void SetSectionAttr_( SwSectionFormat& rSectFormat, const SfxItemSet& rSet ); @@ -174,7 +174,7 @@ public: /** Delete content of all ranges. If whole nodes are selected, these nodes get deleted. */ - bool Delete(); + bool Delete(bool isArtificialSelection = false); /// Remove a complete paragraph. bool DelFullPara(); diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx index 22cd289c7f27..ec18a86241bf 100644 --- a/sw/qa/core/uwriter.cxx +++ b/sw/qa/core/uwriter.cxx @@ -1149,7 +1149,7 @@ void SwDocTest::randomTest() break; case 2: *pCrs->GetMark() = getRandomPosition(m_pDoc, 42); - m_pDoc->getIDocumentContentOperations().DeleteAndJoin(*pCrs, !!getRand(1)); + m_pDoc->getIDocumentContentOperations().DeleteAndJoin(*pCrs, SwDeleteFlags::Default, !!getRand(1)); break; case 3: default: diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index aefb3f438cef..2db40c2e5d57 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -618,8 +618,9 @@ namespace sw namespace { - bool lcl_DoWithBreaks(::sw::DocumentContentOperationsManager & rDocumentContentOperations, SwPaM & rPam, - bool (::sw::DocumentContentOperationsManager::*pFunc)(SwPaM&, bool), const bool bForceJoinNext = false) + bool lcl_DoWithBreaks(::sw::DocumentContentOperationsManager & rDocumentContentOperations, + SwPaM & rPam, SwDeleteFlags const flags, + bool (::sw::DocumentContentOperationsManager::*pFunc)(SwPaM&, SwDeleteFlags, bool), const bool bForceJoinNext = false) { std::vector<std::pair<sal_uLong, sal_Int32>> Breaks; @@ -627,7 +628,7 @@ namespace if (Breaks.empty()) { - return (rDocumentContentOperations.*pFunc)(rPam, bForceJoinNext); + return (rDocumentContentOperations.*pFunc)(rPam, flags, bForceJoinNext); } // Deletion must be split into several parts if the text node @@ -651,7 +652,7 @@ namespace rStart = SwPosition(*rNodes[iter->first - nOffset]->GetTextNode(), iter->second + 1); if (rStart < rEnd) // check if part is empty { - bRet &= (rDocumentContentOperations.*pFunc)(aPam, bForceJoinNext); + bRet &= (rDocumentContentOperations.*pFunc)(aPam, flags, bForceJoinNext); nOffset = iter->first - rStart.nNode.GetIndex(); // deleted fly nodes... } rEnd = SwPosition(*rNodes[iter->first - nOffset]->GetTextNode(), iter->second); @@ -661,7 +662,7 @@ namespace rStart = *rPam.Start(); // set to original start if (rStart < rEnd) // check if part is empty { - bRet &= (rDocumentContentOperations.*pFunc)(aPam, bForceJoinNext); + bRet &= (rDocumentContentOperations.*pFunc)(aPam, flags, bForceJoinNext); } return bRet; @@ -1997,7 +1998,7 @@ void DocumentContentOperationsManager::DeleteDummyChar( assert(aPam.GetText().getLength() == 1 && aPam.GetText()[0] == cDummy); (void) cDummy; - DeleteRangeImpl(aPam); + DeleteRangeImpl(aPam, SwDeleteFlags::Default); if (!m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty()) @@ -2008,7 +2009,7 @@ void DocumentContentOperationsManager::DeleteDummyChar( void DocumentContentOperationsManager::DeleteRange( SwPaM & rPam ) { - lcl_DoWithBreaks( *this, rPam, &DocumentContentOperationsManager::DeleteRangeImpl ); + lcl_DoWithBreaks(*this, rPam, SwDeleteFlags::Default, &DocumentContentOperationsManager::DeleteRangeImpl); if (!m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty()) @@ -2111,7 +2112,7 @@ bool DocumentContentOperationsManager::DelFullPara( SwPaM& rPam ) ::PaMCorrAbs( aDelPam, aTmpPos ); } - std::unique_ptr<SwUndoDelete> pUndo(new SwUndoDelete( aDelPam, true )); + std::unique_ptr<SwUndoDelete> pUndo(new SwUndoDelete(aDelPam, SwDeleteFlags::Default, true)); *rPam.GetPoint() = *aDelPam.GetPoint(); pUndo->SetPgBrkFlags( bSavePageBreak, bSavePageDesc ); @@ -2206,13 +2207,13 @@ bool DocumentContentOperationsManager::DelFullPara( SwPaM& rPam ) } // #i100466# Add handling of new optional parameter <bForceJoinNext> -bool DocumentContentOperationsManager::DeleteAndJoin( SwPaM & rPam, +bool DocumentContentOperationsManager::DeleteAndJoin(SwPaM & rPam, SwDeleteFlags const flags, const bool bForceJoinNext ) { if ( lcl_StrLenOverflow( rPam ) ) return false; - bool const ret = lcl_DoWithBreaks( *this, rPam, (m_rDoc.getIDocumentRedlineAccess().IsRedlineOn()) + bool const ret = lcl_DoWithBreaks( *this, rPam, flags, (m_rDoc.getIDocumentRedlineAccess().IsRedlineOn()) ? &DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl : &DocumentContentOperationsManager::DeleteAndJoinImpl, bForceJoinNext ); @@ -3345,8 +3346,8 @@ bool DocumentContentOperationsManager::ReplaceRange( SwPaM& rPam, const OUString if (rStart < rEnd) // check if part is empty { bRet &= (m_rDoc.getIDocumentRedlineAccess().IsRedlineOn()) - ? DeleteAndJoinWithRedlineImpl(aPam) - : DeleteAndJoinImpl(aPam, false); + ? DeleteAndJoinWithRedlineImpl(aPam, SwDeleteFlags::Default) + : DeleteAndJoinImpl(aPam, SwDeleteFlags::Default, false); nOffset = iter->first - rStart.nNode.GetIndex(); // deleted fly nodes... } rEnd = SwPosition(*rNodes[iter->first - nOffset]->GetTextNode(), iter->second); @@ -3914,7 +3915,7 @@ DocumentContentOperationsManager::~DocumentContentOperationsManager() } //Private methods -bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPam, const bool ) +bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl(SwPaM & rPam, SwDeleteFlags const /*flags*/, const bool) { assert(m_rDoc.getIDocumentRedlineAccess().IsRedlineOn()); @@ -4055,7 +4056,7 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPa return true; } -bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam, +bool DocumentContentOperationsManager::DeleteAndJoinImpl(SwPaM & rPam, SwDeleteFlags const flags, const bool bForceJoinNext ) { bool bJoinText, bJoinPrev; @@ -4067,7 +4068,7 @@ bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam, } { - bool const bSuccess( DeleteRangeImpl( rPam ) ); + bool const bSuccess( DeleteRangeImpl(rPam, flags) ); if (!bSuccess) return false; } @@ -4086,14 +4087,14 @@ bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam, return true; } -bool DocumentContentOperationsManager::DeleteRangeImpl(SwPaM & rPam, const bool) +bool DocumentContentOperationsManager::DeleteRangeImpl(SwPaM & rPam, SwDeleteFlags const flags, const bool) { // Move all cursors out of the deleted range, but first copy the // passed PaM, because it could be a cursor that would be moved! SwPaM aDelPam( *rPam.GetMark(), *rPam.GetPoint() ); ::PaMCorrAbs( aDelPam, *aDelPam.GetPoint() ); - bool const bSuccess( DeleteRangeImplImpl( aDelPam ) ); + bool const bSuccess( DeleteRangeImplImpl(aDelPam, flags) ); if (bSuccess) { // now copy position from temp copy to given PaM *rPam.GetPoint() = *aDelPam.GetPoint(); @@ -4102,7 +4103,7 @@ bool DocumentContentOperationsManager::DeleteRangeImpl(SwPaM & rPam, const bool) return bSuccess; } -bool DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM & rPam) +bool DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM & rPam, SwDeleteFlags const flags) { SwPosition *pStt = rPam.Start(), *pEnd = rPam.End(); @@ -4167,7 +4168,7 @@ bool DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM & rPam) } if (!bMerged) { - m_rDoc.GetIDocumentUndoRedo().AppendUndo( std::make_unique<SwUndoDelete>( rPam ) ); + m_rDoc.GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoDelete>(rPam, flags)); } m_rDoc.getIDocumentState().SetModified(); @@ -4179,8 +4180,11 @@ bool DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM & rPam) m_rDoc.getIDocumentRedlineAccess().DeleteRedline( rPam, true, RedlineType::Any ); // Delete and move all "Flys at the paragraph", which are within the Selection - DelFlyInRange(rPam.GetMark()->nNode, rPam.GetPoint()->nNode, - &rPam.GetMark()->nContent, &rPam.GetPoint()->nContent); + if (!(flags & SwDeleteFlags::ArtificialSelection)) + { + DelFlyInRange(rPam.GetMark()->nNode, rPam.GetPoint()->nNode, + &rPam.GetMark()->nContent, &rPam.GetPoint()->nContent); + } DelBookmarks( pStt->nNode, pEnd->nNode, diff --git a/sw/source/core/docnode/ndsect.cxx b/sw/source/core/docnode/ndsect.cxx index 8c2efee0eb7e..6154cfc7d776 100644 --- a/sw/source/core/docnode/ndsect.cxx +++ b/sw/source/core/docnode/ndsect.cxx @@ -535,7 +535,7 @@ void SwDoc::DelSectionFormat( SwSectionFormat *pFormat, bool bDelNodes ) { SwNodeIndex aUpdIdx( *pIdx ); SwPaM aPaM( *pSectNd->EndOfSectionNode(), *pSectNd ); - GetIDocumentUndoRedo().AppendUndo( std::make_unique<SwUndoDelete>( aPaM )); + GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoDelete>(aPaM, SwDeleteFlags::Default)); if( pFootnoteEndAtTextEnd ) GetFootnoteIdxs().UpdateFootnote( aUpdIdx ); getIDocumentState().SetModified(); diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx index 030f180db237..e6731feba860 100644 --- a/sw/source/core/docnode/ndtbl.cxx +++ b/sw/source/core/docnode/ndtbl.cxx @@ -2040,7 +2040,7 @@ bool SwDoc::DeleteRowCol( const SwSelBoxes& rBoxes, bool bColumn ) bSavePageBreak = true; } } - std::unique_ptr<SwUndoDelete> pUndo(new SwUndoDelete( aPaM )); + std::unique_ptr<SwUndoDelete> pUndo(new SwUndoDelete(aPaM, SwDeleteFlags::Default)); if( bNewTextNd ) pUndo->SetTableDelLastNd(); pUndo->SetPgBrkFlags( bSavePageBreak, bSavePageDesc ); diff --git a/sw/source/core/edit/autofmt.cxx b/sw/source/core/edit/autofmt.cxx index c07cf4ceb18b..80b91de1d649 100644 --- a/sw/source/core/edit/autofmt.cxx +++ b/sw/source/core/edit/autofmt.cxx @@ -1196,7 +1196,7 @@ void SwAutoFormat::DeleteSelImpl(SwPaM & rDelPam, SwPaM & rPamToCorrect) SwPaM* pPrev = rPamToCorrect.GetPrev(); rPamToCorrect.GetRingContainer().merge( pShCursor->GetRingContainer() ); - m_pEditShell->DeleteSel( rDelPam ); + m_pEditShell->DeleteSel(rDelPam, true); // and remove Pam again: SwPaM* p; @@ -1212,7 +1212,7 @@ void SwAutoFormat::DeleteSelImpl(SwPaM & rDelPam, SwPaM & rPamToCorrect) m_pCurTextFrame = GetFrame(*m_pCurTextNd); // keep it up to date } else - m_pEditShell->DeleteSel( rDelPam ); + m_pEditShell->DeleteSel(rDelPam, true); } bool SwAutoFormat::DeleteJoinCurNextPara(SwTextFrame const*const pNextFrame, diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx index 74e845353566..37c19e60a91e 100644 --- a/sw/source/core/edit/eddel.cxx +++ b/sw/source/core/edit/eddel.cxx @@ -38,7 +38,7 @@ #include <strings.hrc> #include <vector> -void SwEditShell::DeleteSel( SwPaM& rPam, bool* pUndo ) +void SwEditShell::DeleteSel(SwPaM& rPam, bool const isArtificialSelection, bool *const pUndo) { bool bSelectAll = StartsWithTable() && ExtendedSelectedAll(); // only for selections @@ -121,7 +121,8 @@ void SwEditShell::DeleteSel( SwPaM& rPam, bool* pUndo ) pPam = pNewPam.get(); } // delete everything - GetDoc()->getIDocumentContentOperations().DeleteAndJoin(*pPam); + GetDoc()->getIDocumentContentOperations().DeleteAndJoin(*pPam, + isArtificialSelection ? SwDeleteFlags::ArtificialSelection : SwDeleteFlags::Default); SaveTableBoxContent( pPam->GetPoint() ); } @@ -129,7 +130,7 @@ void SwEditShell::DeleteSel( SwPaM& rPam, bool* pUndo ) rPam.DeleteMark(); } -bool SwEditShell::Delete() +bool SwEditShell::Delete(bool const isArtificialSelection) { SET_CURR_SHELL( this ); bool bRet = false; @@ -148,7 +149,7 @@ bool SwEditShell::Delete() for(SwPaM& rPaM : GetCursor()->GetRingContainer()) { - DeleteSel( rPaM, &bUndo ); + DeleteSel(rPaM, isArtificialSelection, &bUndo); } // If undo container then close here diff --git a/sw/source/core/edit/edglbldc.cxx b/sw/source/core/edit/edglbldc.cxx index 3d916edc5fe0..c5ea9081d043 100644 --- a/sw/source/core/edit/edglbldc.cxx +++ b/sw/source/core/edit/edglbldc.cxx @@ -272,7 +272,7 @@ void SwEditShell::DeleteGlobalDocContent( const SwGlblDocContents& rArr , rPos.nNode = pMyDoc->GetNodes().GetEndOfContent(); --rPos.nNode; if( !pMyDoc->getIDocumentContentOperations().DelFullPara( *pCursor ) ) - Delete(); + Delete(false); } break; diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx index 8f84ce42ed75..699997003daf 100644 --- a/sw/source/core/edit/editsh.cxx +++ b/sw/source/core/edit/editsh.cxx @@ -663,7 +663,7 @@ bool SwEditShell::InsertURL( const SwFormatINetFormat& rFormat, const OUString& bDelText = bInsText = false; if( bDelText ) - Delete(); + Delete(true); } else if( pCursor->IsMultiSelection() && rFormat.GetValue() == rStr ) bInsText = false; @@ -732,7 +732,7 @@ void SwEditShell::DelINetAttrWithText() { bool bRet = SelectTextAttr( RES_TXTATR_INETFMT, false ); if( bRet ) - DeleteSel( *GetCursor() ); + DeleteSel(*GetCursor(), true); } /// Set the DontExpand flag at the text character attributes diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx index c2470b997a93..8589b8eed579 100644 --- a/sw/source/core/frmedt/fecopy.cxx +++ b/sw/source/core/frmedt/fecopy.cxx @@ -1021,7 +1021,7 @@ bool SwFEShell::Paste( SwDoc* pClpDoc, bool bNestedTable ) { if( bDelTable && IsTableMode() ) { - SwEditShell::Delete(); + SwEditShell::Delete(false); bDelTable = false; } diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx index 2d600b6ff8ba..994812dc14b4 100644 --- a/sw/source/core/inc/DocumentContentOperationsManager.hxx +++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx @@ -48,6 +48,7 @@ public: // Add optional parameter <bForceJoinNext>, default value <false> // Needed for hiding of deletion redlines bool DeleteAndJoin( SwPaM&, + SwDeleteFlags flags = SwDeleteFlags::Default, const bool bForceJoinNext = false ) override; bool MoveRange(SwPaM&, SwPosition&, SwMoveFlags) override; @@ -159,10 +160,10 @@ public: private: SwDoc& m_rDoc; - bool DeleteAndJoinImpl(SwPaM&, const bool); - bool DeleteAndJoinWithRedlineImpl(SwPaM&, const bool unused = false); - bool DeleteRangeImpl(SwPaM&, const bool unused = false); - bool DeleteRangeImplImpl(SwPaM &); + bool DeleteAndJoinImpl(SwPaM&, SwDeleteFlags, const bool); + bool DeleteAndJoinWithRedlineImpl(SwPaM&, SwDeleteFlags, const bool unused = false); + bool DeleteRangeImpl(SwPaM&, SwDeleteFlags, const bool unused = false); + bool DeleteRangeImplImpl(SwPaM &, SwDeleteFlags); bool ReplaceRangeImpl(SwPaM&, OUString const&, const bool); SwFlyFrameFormat* InsNoTextNode( const SwPosition&rPos, SwNoTextNode*, const SfxItemSet* pFlyAttrSet, diff --git a/sw/source/core/inc/UndoDelete.hxx b/sw/source/core/inc/UndoDelete.hxx index a4eb066581c9..b4ae4544d669 100644 --- a/sw/source/core/inc/UndoDelete.hxx +++ b/sw/source/core/inc/UndoDelete.hxx @@ -27,6 +27,7 @@ class SwRedlineSaveDatas; class SwTextNode; +enum class SwDeleteFlags; namespace sfx2 { class MetadatableUndo; @@ -59,6 +60,7 @@ class SwUndoDelete bool m_bResetPgDesc : 1; // TRUE: reset PgDsc on following node bool m_bResetPgBrk : 1; // TRUE: reset PgBreak on following node bool const m_bFromTableCopy : 1; // TRUE: called by SwUndoTableCpyTable + SwDeleteFlags m_DeleteFlags; bool SaveContent( const SwPosition* pStt, const SwPosition* pEnd, SwTextNode* pSttTextNd, SwTextNode* pEndTextNd ); @@ -66,6 +68,7 @@ class SwUndoDelete public: SwUndoDelete( SwPaM&, + SwDeleteFlags flags, bool bFullPara = false, bool bCalledByTableCpy = false ); virtual ~SwUndoDelete() override; diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx index 79235781896d..884d791caebe 100644 --- a/sw/source/core/layout/atrfrm.cxx +++ b/sw/source/core/layout/atrfrm.cxx @@ -3363,7 +3363,7 @@ SwHandleAnchorNodeChg::~SwHandleAnchorNodeChg() COVERITY_NOEXCEPT_FALSE mpWrtShell->SwEditShell::Copy(mpWrtShell); mpWrtShell->DestroyCursor(); - mpWrtShell->Delete(); + mpWrtShell->Delete(false); mpWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent); } diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx index 5f8d08168254..cb819d5216c8 100644 --- a/sw/source/core/undo/undel.cxx +++ b/sw/source/core/undo/undel.cxx @@ -172,6 +172,7 @@ static void DelFullParaMoveFrames(SwDoc & rDoc, SwUndRng const& rRange, // move the paragraph into this section and to record this in nSectDiff. SwUndoDelete::SwUndoDelete( SwPaM& rPam, + SwDeleteFlags const flags, bool bFullPara, bool bCalledByTableCpy ) : SwUndo(SwUndoId::DELETE, rPam.GetDoc()), @@ -190,7 +191,9 @@ SwUndoDelete::SwUndoDelete( m_bResetPgDesc( false ), m_bResetPgBrk( false ), m_bFromTableCopy( bCalledByTableCpy ) + , m_DeleteFlags(flags) { + assert(!m_bDelFullPara || !(m_DeleteFlags & SwDeleteFlags::ArtificialSelection)); m_bCacheComment = false; @@ -226,7 +229,9 @@ SwUndoDelete::SwUndoDelete( } else { - DelContentIndex( *rPam.GetMark(), *rPam.GetPoint() ); + DelContentIndex(*rPam.GetMark(), *rPam.GetPoint(), + DelContentType::AllMask + | ((m_DeleteFlags & SwDeleteFlags::ArtificialSelection) ? DelContentType::Replace : DelContentType(0))); ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo()); if (m_nEndNode - m_nSttNode > 1) // check for fully selected nodes { @@ -1200,7 +1205,11 @@ void SwUndoDelete::RedoImpl(::sw::UndoRedoContext & rContext) DelBookmarks(rPam.GetMark()->nNode, rPam.GetPoint()->nNode); } else - DelContentIndex( *rPam.GetMark(), *rPam.GetPoint() ); + { + DelContentIndex(*rPam.GetMark(), *rPam.GetPoint(), + DelContentType::AllMask + | ((m_DeleteFlags & SwDeleteFlags::ArtificialSelection) ? DelContentType::Replace : DelContentType(0))); + } m_nSetPos = m_pHistory ? m_pHistory->Count() : 0; m_pHistory->Move( m_nSetPos, &aHstr ); @@ -1216,7 +1225,11 @@ void SwUndoDelete::RedoImpl(::sw::UndoRedoContext & rContext) DelBookmarks( rPam.GetMark()->nNode, rPam.GetPoint()->nNode ); } else - DelContentIndex( *rPam.GetMark(), *rPam.GetPoint() ); + { + DelContentIndex(*rPam.GetMark(), *rPam.GetPoint(), + DelContentType::AllMask + | ((m_DeleteFlags & SwDeleteFlags::ArtificialSelection) ? DelContentType::Replace : DelContentType(0))); + } m_nSetPos = m_pHistory ? m_pHistory->Count() : 0; } @@ -1291,7 +1304,7 @@ void SwUndoDelete::RedoImpl(::sw::UndoRedoContext & rContext) rDoc.getIDocumentContentOperations().DelFullPara( rPam ); } else - rDoc.getIDocumentContentOperations().DeleteAndJoin( rPam ); + rDoc.getIDocumentContentOperations().DeleteAndJoin(rPam, m_DeleteFlags); } void SwUndoDelete::RepeatImpl(::sw::RepeatContext & rContext) diff --git a/sw/source/core/undo/unins.cxx b/sw/source/core/undo/unins.cxx index 85b20fae911b..6135466bf73d 100644 --- a/sw/source/core/undo/unins.cxx +++ b/sw/source/core/undo/unins.cxx @@ -917,7 +917,7 @@ void SwUndoInsertLabel::UndoImpl(::sw::UndoRedoContext & rContext) aPam.GetPoint()->nNode = NODE.nNode; aPam.SetMark(); aPam.GetPoint()->nNode = NODE.nNode + 1; - NODE.pUndoInsNd = new SwUndoDelete( aPam, true ); + NODE.pUndoInsNd = new SwUndoDelete(aPam, SwDeleteFlags::Default, true); } } diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx index 8aae3c055b63..117a7992ff50 100644 --- a/sw/source/core/undo/unredln.cxx +++ b/sw/source/core/undo/unredln.cxx @@ -449,7 +449,7 @@ void SwUndoCompDoc::UndoImpl(::sw::UndoRedoContext & rContext) bool bJoinText, bJoinPrev; sw_GetJoinFlags(rPam, bJoinText, bJoinPrev); - pUnDel.reset( new SwUndoDelete(rPam, false) ); + pUnDel.reset( new SwUndoDelete(rPam, SwDeleteFlags::Default, false) ); if( bJoinText ) sw_JoinText(rPam, bJoinPrev); @@ -466,7 +466,7 @@ void SwUndoCompDoc::UndoImpl(::sw::UndoRedoContext & rContext) ++rPam.GetPoint()->nNode; rPam.GetBound().nContent.Assign( nullptr, 0 ); rPam.GetBound( false ).nContent.Assign( nullptr, 0 ); - pUnDel2.reset( new SwUndoDelete(rPam, true) ); + pUnDel2.reset( new SwUndoDelete(rPam, SwDeleteFlags::Default, true) ); } } rPam.DeleteMark(); diff --git a/sw/source/core/undo/untbl.cxx b/sw/source/core/undo/untbl.cxx index 9d1675c0f304..c7dbc781225b 100644 --- a/sw/source/core/undo/untbl.cxx +++ b/sw/source/core/undo/untbl.cxx @@ -2420,11 +2420,11 @@ void SwUndoTableCpyTable::UndoImpl(::sw::UndoRedoContext & rContext) else *aPam.GetPoint() = SwPosition( aTmpIdx ); } - pUndo = std::make_unique<SwUndoDelete>( aPam, bDeleteCompleteParagraph, true ); + pUndo = std::make_unique<SwUndoDelete>(aPam, SwDeleteFlags::Default, bDeleteCompleteParagraph, true); } else { - pUndo = std::make_unique<SwUndoDelete>( aPam, true ); + pUndo = std::make_unique<SwUndoDelete>(aPam, SwDeleteFlags::Default, true); if( pEntry->pUndo ) { pEntry->pUndo->UndoImpl(rContext); @@ -2501,7 +2501,9 @@ void SwUndoTableCpyTable::RedoImpl(::sw::UndoRedoContext & rContext) // b62341295: Redline for copying tables - Start. rDoc.GetNodes().MakeTextNode( aInsIdx, rDoc.GetDfltTextFormatColl() ); SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode()); - std::unique_ptr<SwUndo> pUndo = IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags() ) ? nullptr : std::make_unique<SwUndoDelete>( aPam, true ); + std::unique_ptr<SwUndo> pUndo(IDocumentRedlineAccess::IsRedlineOn(GetRedlineFlags()) + ? nullptr + : std::make_unique<SwUndoDelete>(aPam, SwDeleteFlags::Default, true)); if( pEntry->pUndo ) { pEntry->pUndo->UndoImpl(rContext); @@ -2582,7 +2584,7 @@ void SwUndoTableCpyTable::AddBoxBefore( const SwTableBox& rBox, bool bDelContent SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode() ); if( !pDoc->getIDocumentRedlineAccess().IsRedlineOn() ) - pEntry->pUndo = std::make_unique<SwUndoDelete>( aPam, true ); + pEntry->pUndo = std::make_unique<SwUndoDelete>(aPam, SwDeleteFlags::Default, true); } pEntry->pBoxNumAttr = std::make_unique<SfxItemSet>( @@ -2682,7 +2684,7 @@ std::unique_ptr<SwUndo> SwUndoTableCpyTable::PrepareRedline( SwDoc* pDoc, const aCellEnd = SwPosition( SwNodeIndex( *rBox.GetSttNd()->EndOfSectionNode() )); SwPaM aTmpPam( aDeleteStart, aCellEnd ); - pUndo = std::make_unique<SwUndoDelete>( aTmpPam, true ); + pUndo = std::make_unique<SwUndoDelete>(aTmpPam, SwDeleteFlags::Default, true); } SwPosition aCellStart( SwNodeIndex( *rBox.GetSttNd(), 2 ) ); pText = aCellStart.nNode.GetNode().GetTextNode(); @@ -2754,7 +2756,7 @@ void SwUndoCpyTable::UndoImpl(::sw::UndoRedoContext & rContext) } SwPaM aPam( *pTNd, *pTNd->EndOfSectionNode(), 0 , 1 ); - pDel.reset( new SwUndoDelete( aPam, true ) ); + pDel.reset( new SwUndoDelete( aPam, SwDeleteFlags::Default, true ) ); } void SwUndoCpyTable::RedoImpl(::sw::UndoRedoContext & rContext) diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx index cd4767fc921e..244e95de182c 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -3950,7 +3950,7 @@ bool SwTransferable::PrivateDrop( SwWrtShell& rSh, const Point& rDragPt, if ( bTableSel ) { /* delete table contents not cells */ - rSrcSh.Delete(); + rSrcSh.Delete(false); } else { diff --git a/sw/source/uibase/lingu/hhcwrp.cxx b/sw/source/uibase/lingu/hhcwrp.cxx index 52ee334ec21d..55f09447c623 100644 --- a/sw/source/uibase/lingu/hhcwrp.cxx +++ b/sw/source/uibase/lingu/hhcwrp.cxx @@ -326,7 +326,7 @@ void SwHHCWrapper::ChangeText_impl( const OUString &rNewText, bool bKeepAttribut // restore those for the new text m_rWrtShell.GetCurAttr( aItemSet ); - m_rWrtShell.Delete(); + m_rWrtShell.Delete(true); m_rWrtShell.Insert( rNewText ); // select new inserted text (currently the Point is right after the new text) @@ -346,7 +346,7 @@ void SwHHCWrapper::ChangeText_impl( const OUString &rNewText, bool bKeepAttribut } else { - m_rWrtShell.Delete(); + m_rWrtShell.Delete(true); m_rWrtShell.Insert( rNewText ); } } diff --git a/sw/source/uibase/ribbar/inputwin.cxx b/sw/source/uibase/ribbar/inputwin.cxx index 1c278137cb16..fdab2b6ec5de 100644 --- a/sw/source/uibase/ribbar/inputwin.cxx +++ b/sw/source/uibase/ribbar/inputwin.cxx @@ -245,7 +245,7 @@ void SwInputWindow::ShowWin() if( pWrtShell->SwCursorShell::HasSelection() ) { pWrtShell->StartUndo( SwUndoId::DELETE ); - pWrtShell->Delete(); + pWrtShell->Delete(false); if( SwUndoId::EMPTY != pWrtShell->EndUndo( SwUndoId::DELETE )) { m_bCallUndo = true; @@ -451,7 +451,7 @@ void SwInputWindow::DelBoxContent() pWrtShell->MoveSection( GoCurrSection, fnSectionStart ); pWrtShell->SetMark(); pWrtShell->MoveSection( GoCurrSection, fnSectionEnd ); - pWrtShell->SwEditShell::Delete(); + pWrtShell->SwEditShell::Delete(false); pWrtShell->EndAllAction(); } } diff --git a/sw/source/uibase/wrtsh/delete.cxx b/sw/source/uibase/wrtsh/delete.cxx index 4a2420ad7b84..5358876d204d 100644 --- a/sw/source/uibase/wrtsh/delete.cxx +++ b/sw/source/uibase/wrtsh/delete.cxx @@ -104,7 +104,7 @@ void SwWrtShell::DelLine() SetMark(); SwCursorShell::RightMargin(); - bool bRet = Delete(); + bool bRet = Delete(false); Pop(SwCursorShell::PopMode::DeleteCurrent); if( bRet ) UpdateAttr(); @@ -114,7 +114,7 @@ void SwWrtShell::DelToStartOfLine() { OpenMark(); SwCursorShell::LeftMargin(); - bool bRet = Delete(); + bool bRet = Delete(false); CloseMark( bRet ); } @@ -122,7 +122,7 @@ void SwWrtShell::DelToEndOfLine() { OpenMark(); SwCursorShell::RightMargin(); - bool bRet = Delete(); + bool bRet = Delete(false); CloseMark( bRet ); } @@ -164,7 +164,7 @@ bool SwWrtShell::DelLeft() { SwActContext aActContext(this); ResetCursorStack(); - Delete(); + Delete(false); UpdateAttr(); } if( IsBlockMode() ) @@ -275,7 +275,7 @@ bool SwWrtShell::DelLeft() } } } - bool bRet = Delete(); + bool bRet = Delete(true); if( !bRet && bSwap ) SwCursorShell::SwapPam(); CloseMark( bRet ); @@ -309,7 +309,7 @@ bool SwWrtShell::DelRight() { SwActContext aActContext(this); ResetCursorStack(); - Delete(); + Delete(false); UpdateAttr(); } if( IsBlockMode() ) @@ -392,7 +392,7 @@ bool SwWrtShell::DelRight() OpenMark(); SwCursorShell::Right(1, CRSR_SKIP_CELLS); - bRet = Delete(); + bRet = Delete(true); CloseMark( bRet ); break; @@ -498,7 +498,7 @@ void SwWrtShell::DelToEndOfPara() Pop(SwCursorShell::PopMode::DeleteCurrent); return; } - bool bRet = Delete(); + bool bRet = Delete(false); Pop(SwCursorShell::PopMode::DeleteCurrent); if( bRet ) UpdateAttr(); @@ -515,7 +515,7 @@ void SwWrtShell::DelToStartOfPara() Pop(SwCursorShell::PopMode::DeleteCurrent); return; } - bool bRet = Delete(); + bool bRet = Delete(false); Pop(SwCursorShell::PopMode::DeleteCurrent); if( bRet ) UpdateAttr(); @@ -530,7 +530,7 @@ void SwWrtShell::DelToStartOfSentence() if(IsStartOfDoc()) return; OpenMark(); - bool bRet = BwdSentence_() && Delete(); + bool bRet = BwdSentence_() && Delete(false); CloseMark( bRet ); } @@ -562,7 +562,7 @@ bool SwWrtShell::DelToEndOfSentence() } else { - bRet = FwdSentence_() && Delete(); + bRet = FwdSentence_() && Delete(false); } CloseMark( bRet ); return bRet; @@ -583,7 +583,7 @@ void SwWrtShell::DelNxtWord() else EndWrd(); - bool bRet = Delete(); + bool bRet = Delete(false); if( bRet ) UpdateAttr(); else @@ -607,7 +607,7 @@ void SwWrtShell::DelPrvWord() else SttWrd(); } - bool bRet = Delete(); + bool bRet = Delete(false); if( bRet ) UpdateAttr(); else diff --git a/sw/source/uibase/wrtsh/select.cxx b/sw/source/uibase/wrtsh/select.cxx index 90664ae098f5..322199a2b1d5 100644 --- a/sw/source/uibase/wrtsh/select.cxx +++ b/sw/source/uibase/wrtsh/select.cxx @@ -914,7 +914,7 @@ int SwWrtShell::IntelligentCut(SelectionType nSelection, bool bCut) ClearMark(); SetMark(); SwCursorShell::Left(1,CRSR_SKIP_CHARS); - SwFEShell::Delete(); + SwFEShell::Delete(true); Pop(SwCursorShell::PopMode::DeleteCurrent); } } @@ -928,7 +928,7 @@ int SwWrtShell::IntelligentCut(SelectionType nSelection, bool bCut) ClearMark(); SetMark(); SwCursorShell::Right(1,CRSR_SKIP_CHARS); - SwFEShell::Delete(); + SwFEShell::Delete(true); Pop(SwCursorShell::PopMode::DeleteCurrent); } }