sw/inc/IDocumentContentOperations.hxx | 11 +++ sw/inc/editsh.hxx | 4 - sw/qa/extras/uiwriter/uiwriter3.cxx | 6 +- sw/qa/uitest/writer_tests7/tdf137802.py | 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/frmedt/fetab.cxx | 4 - 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/docvw/edtwin.cxx | 2 sw/source/uibase/lingu/hhcwrp.cxx | 4 - sw/source/uibase/ribbar/inputwin.cxx | 4 - sw/source/uibase/utlui/content.cxx | 2 sw/source/uibase/wrtsh/delete.cxx | 28 ++++----- sw/source/uibase/wrtsh/select.cxx | 4 - 27 files changed, 119 insertions(+), 80 deletions(-)
New commits: commit 5192cd430e8cab0ed04f8c70c5194397455ac705 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Tue Jun 7 19:01:24 2022 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Jun 10 13:07:29 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) Change-Id: Ib4467476b12a12aefbbcb74ab9802f9318cf9aa0 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> diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx index 8f082a632d73..6faaf62fccf4 100644 --- a/sw/inc/IDocumentContentOperations.hxx +++ b/sw/inc/IDocumentContentOperations.hxx @@ -82,6 +82,16 @@ namespace o3tl template<> struct typed_flags<SwCopyFlags> : is_typed_flags<SwCopyFlags, 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 @@ -144,6 +154,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 72571775af91..e07c287e4a3f 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -150,7 +150,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 ); @@ -172,7 +172,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/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx index 1b90efde6bac..068a14113a0b 100644 --- a/sw/qa/extras/uiwriter/uiwriter3.cxx +++ b/sw/qa/extras/uiwriter/uiwriter3.cxx @@ -1424,7 +1424,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf132725) dispatchCommand(mxComponent, ".uno:SwBackspace", {}); Scheduler::ProcessEventsToIdle(); - CPPUNIT_ASSERT_EQUAL(0, getShapes()); + // tdf#137587 fly is no longer deleted by backspace + CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(OUString(""), getParagraph(1)->getString()); dispatchCommand(mxComponent, ".uno:Undo", {}); @@ -1438,7 +1439,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf132725) dispatchCommand(mxComponent, ".uno:Redo", {}); Scheduler::ProcessEventsToIdle(); - CPPUNIT_ASSERT_EQUAL(0, getShapes()); + // tdf#137587 fly is no longer deleted by backspace + CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(OUString(""), getParagraph(1)->getString()); //Without the fix in place, it would crash here diff --git a/sw/qa/uitest/writer_tests7/tdf137802.py b/sw/qa/uitest/writer_tests7/tdf137802.py index 424375b3df38..da9f9febd8e5 100644 --- a/sw/qa/uitest/writer_tests7/tdf137802.py +++ b/sw/qa/uitest/writer_tests7/tdf137802.py @@ -49,6 +49,8 @@ class tdf137802(UITestCase): # Delete the second paragraph. Shape 2 is anchored to this paragraph # so it should be deleted + # tdf#137587 fly is no longer deleted by backspace so explictly select + xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "SHIFT+LEFT"})) xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "BACKSPACE"})) self.assertEqual(document.DrawPage.getCount(), 1) diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 965a9024a57d..a52884f8c43a 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -638,8 +638,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<SwNodeOffset, sal_Int32>> Breaks; @@ -647,7 +648,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 @@ -671,7 +672,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); @@ -681,7 +682,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; @@ -2118,7 +2119,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()) @@ -2129,7 +2130,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()) @@ -2232,7 +2233,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 ); @@ -2327,13 +2328,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 ); @@ -3514,8 +3515,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); @@ -4088,7 +4089,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()); @@ -4230,7 +4231,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; @@ -4242,7 +4243,7 @@ bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam, } { - bool const bSuccess( DeleteRangeImpl( rPam ) ); + bool const bSuccess( DeleteRangeImpl(rPam, flags) ); if (!bSuccess) return false; } @@ -4261,14 +4262,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(); @@ -4277,7 +4278,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(); @@ -4342,7 +4343,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(); @@ -4354,8 +4355,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 48a5b0af4700..25669fcd2f76 100644 --- a/sw/source/core/docnode/ndsect.cxx +++ b/sw/source/core/docnode/ndsect.cxx @@ -539,7 +539,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 1b0e09f9b0f2..0deb57013818 100644 --- a/sw/source/core/docnode/ndtbl.cxx +++ b/sw/source/core/docnode/ndtbl.cxx @@ -2065,7 +2065,7 @@ bool SwDoc::DeleteRowCol(const SwSelBoxes& rBoxes, RowColMode const eMode) 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 5b41af36d30c..29d84601f299 100644 --- a/sw/source/core/edit/autofmt.cxx +++ b/sw/source/core/edit/autofmt.cxx @@ -1185,7 +1185,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; @@ -1201,7 +1201,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 94eb7f36abb6..8b19e8c8b1e0 100644 --- a/sw/source/core/edit/eddel.cxx +++ b/sw/source/core/edit/eddel.cxx @@ -31,7 +31,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 @@ -114,7 +114,8 @@ void SwEditShell::DeleteSel( SwPaM& rPam, bool* pUndo ) pPam = &*pNewPam; } // delete everything - GetDoc()->getIDocumentContentOperations().DeleteAndJoin(*pPam); + GetDoc()->getIDocumentContentOperations().DeleteAndJoin(*pPam, + isArtificialSelection ? SwDeleteFlags::ArtificialSelection : SwDeleteFlags::Default); SaveTableBoxContent( pPam->GetPoint() ); } @@ -122,7 +123,7 @@ void SwEditShell::DeleteSel( SwPaM& rPam, bool* pUndo ) rPam.DeleteMark(); } -bool SwEditShell::Delete() +bool SwEditShell::Delete(bool const isArtificialSelection) { CurrShell aCurr( this ); bool bRet = false; @@ -141,7 +142,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 cfc7453a902a..ef7901d50756 100644 --- a/sw/source/core/edit/edglbldc.cxx +++ b/sw/source/core/edit/edglbldc.cxx @@ -271,7 +271,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 3348540fcf29..cafade8c5b90 100644 --- a/sw/source/core/edit/editsh.cxx +++ b/sw/source/core/edit/editsh.cxx @@ -659,7 +659,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; @@ -728,7 +728,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 28a439e2c566..486478dfca20 100644 --- a/sw/source/core/frmedt/fecopy.cxx +++ b/sw/source/core/frmedt/fecopy.cxx @@ -1065,7 +1065,7 @@ bool SwFEShell::Paste(SwDoc& rClpDoc, bool bNestedTable) { if( bDelTable && IsTableMode() ) { - SwEditShell::Delete(); + SwEditShell::Delete(false); bDelTable = false; } diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx index ecb7cfc39f2a..678ebfc2fac7 100644 --- a/sw/source/core/frmedt/fetab.cxx +++ b/sw/source/core/frmedt/fetab.cxx @@ -355,7 +355,7 @@ bool SwFEShell::DeleteRow(bool bCompleteTable) if ( !bRecordAndHideChanges ) { SwEditShell* pEditShell = GetDoc()->GetEditShell(); - pEditShell->Delete(); + pEditShell->Delete(false); EndAllActionAndCall(); EndUndo(bCompleteTable ? SwUndoId::UI_TABLE_DELETE : SwUndoId::ROW_DELETE); @@ -457,7 +457,7 @@ bool SwFEShell::DeleteRow(bool bCompleteTable) pWrtShell->UpdateCursor(); } - pEditShell->Delete(); + pEditShell->Delete(false); } SwNodeOffset nIdx; diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx index e81c62d1d9e0..5434e43f2a9c 100644 --- a/sw/source/core/inc/DocumentContentOperationsManager.hxx +++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx @@ -47,6 +47,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; @@ -163,10 +164,10 @@ private: bool m_bIME = false; - 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 1325dd373af7..2491af658c61 100644 --- a/sw/source/core/inc/UndoDelete.hxx +++ b/sw/source/core/inc/UndoDelete.hxx @@ -28,6 +28,7 @@ class SwRedlineSaveDatas; class SwTextNode; typedef struct _xmlTextWriter* xmlTextWriterPtr; +enum class SwDeleteFlags; namespace sfx2 { class MetadatableUndo; @@ -60,6 +61,7 @@ class SwUndoDelete final bool m_bResetPgDesc : 1; // TRUE: reset PgDsc on following node bool m_bResetPgBrk : 1; // TRUE: reset PgBreak on following node bool m_bFromTableCopy : 1; // TRUE: called by SwUndoTableCpyTable + SwDeleteFlags m_DeleteFlags; bool SaveContent( const SwPosition* pStt, const SwPosition* pEnd, SwTextNode* pSttTextNd, SwTextNode* pEndTextNd ); @@ -67,6 +69,7 @@ class SwUndoDelete final 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 5876f3624c53..fa246799d547 100644 --- a/sw/source/core/layout/atrfrm.cxx +++ b/sw/source/core/layout/atrfrm.cxx @@ -3425,7 +3425,7 @@ void SwHandleAnchorNodeChg::ImplDestroy() 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 2d35811a9b86..37e7b2fb2fc5 100644 --- a/sw/source/core/undo/undel.cxx +++ b/sw/source/core/undo/undel.cxx @@ -173,6 +173,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()), @@ -191,7 +192,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; @@ -225,7 +228,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(rDoc.GetIDocumentUndoRedo()); if (m_nEndNode - m_nSttNode > SwNodeOffset(1)) // check for fully selected nodes { @@ -1201,7 +1206,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 ); @@ -1217,7 +1226,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; } @@ -1292,7 +1305,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 c18f6406e20d..a47fbcc9ed9f 100644 --- a/sw/source/core/undo/unins.cxx +++ b/sw/source/core/undo/unins.cxx @@ -913,7 +913,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 b2cee7f58f3a..eae6577d52ff 100644 --- a/sw/source/core/undo/unredln.cxx +++ b/sw/source/core/undo/unredln.cxx @@ -493,7 +493,7 @@ void SwUndoCompDoc::UndoImpl(::sw::UndoRedoContext & rContext) bool bJoinText, bJoinPrev; sw_GetJoinFlags(rPam, bJoinText, bJoinPrev); - m_pUndoDelete.reset( new SwUndoDelete(rPam, false) ); + m_pUndoDelete.reset(new SwUndoDelete(rPam, SwDeleteFlags::Default, false)); if( bJoinText ) sw_JoinText(rPam, bJoinPrev); @@ -510,7 +510,7 @@ void SwUndoCompDoc::UndoImpl(::sw::UndoRedoContext & rContext) ++rPam.GetPoint()->nNode; rPam.GetBound().nContent.Assign( nullptr, 0 ); rPam.GetBound( false ).nContent.Assign( nullptr, 0 ); - m_pUndoDelete2.reset( new SwUndoDelete(rPam, true) ); + m_pUndoDelete2.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 d5c15a0fbc4a..848668641769 100644 --- a/sw/source/core/undo/untbl.cxx +++ b/sw/source/core/undo/untbl.cxx @@ -2475,11 +2475,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); @@ -2553,7 +2553,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); @@ -2630,7 +2632,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<SfxItemSetFixed< @@ -2732,7 +2734,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(); @@ -2821,7 +2823,7 @@ void SwUndoCpyTable::UndoImpl(::sw::UndoRedoContext & rContext) } SwPaM aPam( *pTNd, *pTNd->EndOfSectionNode(), SwNodeOffset(0) , SwNodeOffset(1) ); - m_pDelete.reset( new SwUndoDelete( aPam, true ) ); + m_pDelete.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 b76476b4e02a..70dfedbb1563 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -4229,7 +4229,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/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index adf0d7847397..ca94c561eadd 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -6514,7 +6514,7 @@ bool SwEditWin::DeleteSurroundingText(const Selection& rSelection) if (rSh.SelectTextView(nStartPos + TextFrameIndex(rSelection.Min()), nStartPos + TextFrameIndex(rSelection.Max()))) { - rSh.Delete(); + rSh.Delete(false); return true; } diff --git a/sw/source/uibase/lingu/hhcwrp.cxx b/sw/source/uibase/lingu/hhcwrp.cxx index eff62f932e9c..319a8a620b7f 100644 --- a/sw/source/uibase/lingu/hhcwrp.cxx +++ b/sw/source/uibase/lingu/hhcwrp.cxx @@ -319,7 +319,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) @@ -339,7 +339,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 26325060cb10..dcf854699f0f 100644 --- a/sw/source/uibase/ribbar/inputwin.cxx +++ b/sw/source/uibase/ribbar/inputwin.cxx @@ -247,7 +247,7 @@ void SwInputWindow::ShowWin() if( m_pWrtShell->SwCursorShell::HasSelection() ) { m_pWrtShell->StartUndo( SwUndoId::DELETE ); - m_pWrtShell->Delete(); + m_pWrtShell->Delete(false); if( SwUndoId::EMPTY != m_pWrtShell->EndUndo( SwUndoId::DELETE )) { m_bCallUndo = true; @@ -469,7 +469,7 @@ void SwInputWindow::DelBoxContent() m_pWrtShell->MoveSection( GoCurrSection, fnSectionStart ); m_pWrtShell->SetMark(); m_pWrtShell->MoveSection( GoCurrSection, fnSectionEnd ); - m_pWrtShell->SwEditShell::Delete(); + m_pWrtShell->SwEditShell::Delete(false); m_pWrtShell->EndAllAction(); } } diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 4985e4f2075e..22f54c2ab334 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -4728,7 +4728,7 @@ void SwContentTree::DeleteOutlineSelections() SwRewriter aRewriter; aRewriter.AddRule(UndoArg1, SwResId(STR_CHAPTERS, nChapters)); m_pActiveShell->StartUndo(SwUndoId::DELETE, &aRewriter); - m_pActiveShell->Delete(); + m_pActiveShell->Delete(false); m_pActiveShell->EndUndo(); m_pActiveShell->EndAction(); diff --git a/sw/source/uibase/wrtsh/delete.cxx b/sw/source/uibase/wrtsh/delete.cxx index c33f014f8f31..96ea6f56816d 100644 --- a/sw/source/uibase/wrtsh/delete.cxx +++ b/sw/source/uibase/wrtsh/delete.cxx @@ -110,7 +110,7 @@ void SwWrtShell::DelLine() SetMark(); SwCursorShell::RightMargin(); - bool bRet = Delete(); + bool bRet = Delete(false); Pop(SwCursorShell::PopMode::DeleteCurrent); if( bRet ) UpdateAttr(); @@ -120,7 +120,7 @@ void SwWrtShell::DelToStartOfLine() { OpenMark(); SwCursorShell::LeftMargin(); - bool bRet = Delete(); + bool bRet = Delete(false); CloseMark( bRet ); } @@ -128,7 +128,7 @@ void SwWrtShell::DelToEndOfLine() { OpenMark(); SwCursorShell::RightMargin(); - bool bRet = Delete(); + bool bRet = Delete(false); CloseMark( bRet ); } @@ -170,7 +170,7 @@ bool SwWrtShell::DelLeft() { SwActContext aActContext(this); ResetCursorStack(); - Delete(); + Delete(false); UpdateAttr(); } if( IsBlockMode() ) @@ -279,7 +279,7 @@ bool SwWrtShell::DelLeft() } } } - bool bRet = Delete(); + bool bRet = Delete(true); if( !bRet && bSwap ) SwCursorShell::SwapPam(); CloseMark( bRet ); @@ -319,7 +319,7 @@ bool SwWrtShell::DelRight() { SwActContext aActContext(this); ResetCursorStack(); - Delete(); + Delete(false); UpdateAttr(); } if( IsBlockMode() ) @@ -402,7 +402,7 @@ bool SwWrtShell::DelRight() OpenMark(); SwCursorShell::Right(1, CRSR_SKIP_CELLS); - bRet = Delete(); + bRet = Delete(true); CloseMark( bRet ); if (!bRet) { // false indicates HasReadonlySel failed @@ -485,7 +485,7 @@ bool SwWrtShell::DelRight() } OpenMark(); SwCursorShell::Right(nRedlineLength, CRSR_SKIP_CHARS); - bRet = Delete(); + bRet = Delete(false); CloseMark( bRet ); } else @@ -561,7 +561,7 @@ void SwWrtShell::DelToEndOfPara() Pop(SwCursorShell::PopMode::DeleteCurrent); return; } - bool bRet = Delete(); + bool bRet = Delete(false); Pop(SwCursorShell::PopMode::DeleteCurrent); if( bRet ) UpdateAttr(); @@ -578,7 +578,7 @@ void SwWrtShell::DelToStartOfPara() Pop(SwCursorShell::PopMode::DeleteCurrent); return; } - bool bRet = Delete(); + bool bRet = Delete(false); Pop(SwCursorShell::PopMode::DeleteCurrent); if( bRet ) UpdateAttr(); @@ -593,7 +593,7 @@ void SwWrtShell::DelToStartOfSentence() if(IsStartOfDoc()) return; OpenMark(); - bool bRet = BwdSentence_() && Delete(); + bool bRet = BwdSentence_() && Delete(false); CloseMark( bRet ); } @@ -625,7 +625,7 @@ bool SwWrtShell::DelToEndOfSentence() } else { - bRet = FwdSentence_() && Delete(); + bRet = FwdSentence_() && Delete(false); } CloseMark( bRet ); return bRet; @@ -646,7 +646,7 @@ void SwWrtShell::DelNxtWord() else EndWrd(); - bool bRet = Delete(); + bool bRet = Delete(false); if( bRet ) UpdateAttr(); else @@ -670,7 +670,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 33c47745539f..c122162b01fa 100644 --- a/sw/source/uibase/wrtsh/select.cxx +++ b/sw/source/uibase/wrtsh/select.cxx @@ -908,7 +908,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); } } @@ -922,7 +922,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); } }