sw/inc/IDocumentContentOperations.hxx | 12 +++- 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 | 10 +-- 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(+), 82 deletions(-)
New commits: commit 85376a02348810812d515ee72140dbf56f2b6040 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Tue Jun 7 19:01:24 2022 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Wed Jun 8 20:31:40 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> diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx index c9445ebc9281..bac97d685927 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 @@ -139,7 +149,7 @@ public: /** complete delete of a given PaM */ - virtual bool DeleteAndJoin( SwPaM& ) = 0; + virtual bool DeleteAndJoin(SwPaM&, SwDeleteFlags flags = SwDeleteFlags::Default) = 0; virtual bool MoveRange(SwPaM&, SwPosition&, SwMoveFlags) = 0; diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx index db21aaaa658c..67c18d798a12 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 69818b1cff11..3c794a3da60e 100644 --- a/sw/qa/extras/uiwriter/uiwriter3.cxx +++ b/sw/qa/extras/uiwriter/uiwriter3.cxx @@ -1783,7 +1783,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", {}); @@ -1797,7 +1798,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 0a923e64f1a8..2c378664bcfd 100644 --- a/sw/qa/uitest/writer_tests7/tdf137802.py +++ b/sw/qa/uitest/writer_tests7/tdf137802.py @@ -51,6 +51,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 c8797ae48d08..4fcf4519a09f 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -648,8 +648,9 @@ namespace sw namespace { - bool lcl_DoWithBreaks(::sw::DocumentContentOperationsManager & rDocumentContentOperations, SwPaM & rPam, - bool (::sw::DocumentContentOperationsManager::*pFunc)(SwPaM&)) + bool lcl_DoWithBreaks(::sw::DocumentContentOperationsManager & rDocumentContentOperations, + SwPaM & rPam, SwDeleteFlags const flags, + bool (::sw::DocumentContentOperationsManager::*pFunc)(SwPaM&, SwDeleteFlags)) { std::vector<std::pair<SwNodeOffset, sal_Int32>> Breaks; @@ -657,7 +658,7 @@ namespace if (Breaks.empty()) { - return (rDocumentContentOperations.*pFunc)(rPam); + return (rDocumentContentOperations.*pFunc)(rPam, flags); } // Deletion must be split into several parts if the text node @@ -681,7 +682,7 @@ namespace rStart = SwPosition(*rNodes[iter->first - nOffset]->GetTextNode(), iter->second + 1); if (rStart < rEnd) // check if part is empty { - bRet &= (rDocumentContentOperations.*pFunc)(aPam); + bRet &= (rDocumentContentOperations.*pFunc)(aPam, flags); nOffset = iter->first - rStart.nNode.GetIndex(); // deleted fly nodes... } rEnd = SwPosition(*rNodes[iter->first - nOffset]->GetTextNode(), iter->second); @@ -691,7 +692,7 @@ namespace rStart = *rPam.Start(); // set to original start if (rStart < rEnd) // check if part is empty { - bRet &= (rDocumentContentOperations.*pFunc)(aPam); + bRet &= (rDocumentContentOperations.*pFunc)(aPam, flags); } return bRet; @@ -2125,7 +2126,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()) @@ -2136,7 +2137,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()) @@ -2239,7 +2240,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 ); @@ -2333,12 +2334,12 @@ bool DocumentContentOperationsManager::DelFullPara( SwPaM& rPam ) return true; } -bool DocumentContentOperationsManager::DeleteAndJoin( SwPaM & rPam ) +bool DocumentContentOperationsManager::DeleteAndJoin(SwPaM & rPam, SwDeleteFlags const flags) { 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 ); @@ -3531,8 +3532,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); + ? DeleteAndJoinWithRedlineImpl(aPam, SwDeleteFlags::Default) + : DeleteAndJoinImpl(aPam, SwDeleteFlags::Default); nOffset = iter->first - rStart.nNode.GetIndex(); // deleted fly nodes... } rEnd = SwPosition(*rNodes[iter->first - nOffset]->GetTextNode(), iter->second); @@ -4101,7 +4102,7 @@ DocumentContentOperationsManager::~DocumentContentOperationsManager() } //Private methods -bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPam ) +bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl(SwPaM & rPam, SwDeleteFlags const /*flags*/) { assert(m_rDoc.getIDocumentRedlineAccess().IsRedlineOn()); @@ -4243,12 +4244,12 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPa return true; } -bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam ) +bool DocumentContentOperationsManager::DeleteAndJoinImpl(SwPaM & rPam, SwDeleteFlags const flags) { bool bJoinText, bJoinPrev; ::sw_GetJoinFlags( rPam, bJoinText, bJoinPrev ); - bool const bSuccess( DeleteRangeImpl( rPam ) ); + bool const bSuccess( DeleteRangeImpl(rPam, flags) ); if (!bSuccess) return false; @@ -4266,14 +4267,14 @@ bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam ) return true; } -bool DocumentContentOperationsManager::DeleteRangeImpl(SwPaM & rPam) +bool DocumentContentOperationsManager::DeleteRangeImpl(SwPaM & rPam, SwDeleteFlags const flags) { // 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(); @@ -4282,7 +4283,7 @@ bool DocumentContentOperationsManager::DeleteRangeImpl(SwPaM & rPam) return bSuccess; } -bool DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM & rPam) +bool DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM & rPam, SwDeleteFlags const flags) { SwPosition *pStt = rPam.Start(), *pEnd = rPam.End(); @@ -4347,7 +4348,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(); @@ -4359,8 +4360,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 3c6b26b39366..098f5bd49430 100644 --- a/sw/source/core/docnode/ndsect.cxx +++ b/sw/source/core/docnode/ndsect.cxx @@ -541,7 +541,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 8d69ef74faa9..1c1fc32d16a3 100644 --- a/sw/source/core/docnode/ndtbl.cxx +++ b/sw/source/core/docnode/ndtbl.cxx @@ -2054,7 +2054,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 4341e2f7e3c8..a4e0260f3741 100644 --- a/sw/source/core/edit/autofmt.cxx +++ b/sw/source/core/edit/autofmt.cxx @@ -1183,7 +1183,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; @@ -1199,7 +1199,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 092cd786de30..80a97ba33f59 100644 --- a/sw/source/core/edit/edglbldc.cxx +++ b/sw/source/core/edit/edglbldc.cxx @@ -270,7 +270,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 a6a27bcc5b57..060c6417137e 100644 --- a/sw/source/core/edit/editsh.cxx +++ b/sw/source/core/edit/editsh.cxx @@ -658,7 +658,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; @@ -739,7 +739,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 19102b85f0cf..5914514808d2 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 89f0f81da62d..ce6dc7788a86 100644 --- a/sw/source/core/inc/DocumentContentOperationsManager.hxx +++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx @@ -44,7 +44,7 @@ public: bool DelFullPara(SwPaM&) override; - bool DeleteAndJoin( SwPaM& ) override; + bool DeleteAndJoin(SwPaM&, SwDeleteFlags flags = SwDeleteFlags::Default) override; bool MoveRange(SwPaM&, SwPosition&, SwMoveFlags) override; @@ -160,10 +160,10 @@ private: bool m_bIME = false; - bool DeleteAndJoinImpl(SwPaM&); - bool DeleteAndJoinWithRedlineImpl(SwPaM&); - bool DeleteRangeImpl(SwPaM&); - bool DeleteRangeImplImpl(SwPaM &); + bool DeleteAndJoinImpl(SwPaM &, SwDeleteFlags); + bool DeleteAndJoinWithRedlineImpl(SwPaM &, SwDeleteFlags); + bool DeleteRangeImpl(SwPaM &, SwDeleteFlags); + 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 6b654cc001f1..98588785cec3 100644 --- a/sw/source/core/layout/atrfrm.cxx +++ b/sw/source/core/layout/atrfrm.cxx @@ -3423,7 +3423,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 dd6b55ea2f8f..95c9d612b46a 100644 --- a/sw/source/core/undo/undel.cxx +++ b/sw/source/core/undo/undel.cxx @@ -175,6 +175,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()), @@ -193,7 +194,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; @@ -227,7 +230,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 { @@ -1203,7 +1208,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 ); @@ -1219,7 +1228,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; } @@ -1293,7 +1306,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 6e1b421e9517..ab542d9cad45 100644 --- a/sw/source/core/undo/untbl.cxx +++ b/sw/source/core/undo/untbl.cxx @@ -2471,11 +2471,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); @@ -2549,7 +2549,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); @@ -2626,7 +2628,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< @@ -2728,7 +2730,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(); @@ -2816,7 +2818,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 5c3988e458b7..dd9fc88fbe57 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -4224,7 +4224,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 1c29953c30c6..a0effc7db82a 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -6579,7 +6579,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 a472fc3f227c..255ae24335ab 100644 --- a/sw/source/uibase/ribbar/inputwin.cxx +++ b/sw/source/uibase/ribbar/inputwin.cxx @@ -248,7 +248,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; @@ -470,7 +470,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 584b80dfe0c5..de9275d3d1b9 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -4654,7 +4654,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 aabfafde2d7d..5a1a1b031675 100644 --- a/sw/source/uibase/wrtsh/delete.cxx +++ b/sw/source/uibase/wrtsh/delete.cxx @@ -109,7 +109,7 @@ void SwWrtShell::DelLine() SetMark(); SwCursorShell::RightMargin(); - bool bRet = Delete(); + bool bRet = Delete(false); Pop(SwCursorShell::PopMode::DeleteCurrent); if( bRet ) UpdateAttr(); @@ -119,7 +119,7 @@ void SwWrtShell::DelToStartOfLine() { OpenMark(); SwCursorShell::LeftMargin(); - bool bRet = Delete(); + bool bRet = Delete(false); CloseMark( bRet ); } @@ -127,7 +127,7 @@ void SwWrtShell::DelToEndOfLine() { OpenMark(); SwCursorShell::RightMargin(); - bool bRet = Delete(); + bool bRet = Delete(false); CloseMark( bRet ); } @@ -169,7 +169,7 @@ bool SwWrtShell::DelLeft() { SwActContext aActContext(this); ResetCursorStack(); - Delete(); + Delete(false); UpdateAttr(); } if( IsBlockMode() ) @@ -278,7 +278,7 @@ bool SwWrtShell::DelLeft() } } } - bool bRet = Delete(); + bool bRet = Delete(true); if( !bRet && bSwap ) SwCursorShell::SwapPam(); CloseMark( bRet ); @@ -318,7 +318,7 @@ bool SwWrtShell::DelRight() { SwActContext aActContext(this); ResetCursorStack(); - Delete(); + Delete(false); UpdateAttr(); } if( IsBlockMode() ) @@ -401,7 +401,7 @@ bool SwWrtShell::DelRight() OpenMark(); SwCursorShell::Right(1, CRSR_SKIP_CELLS); - bRet = Delete(); + bRet = Delete(true); CloseMark( bRet ); if (!bRet) { // false indicates HasReadonlySel failed @@ -484,7 +484,7 @@ bool SwWrtShell::DelRight() } OpenMark(); SwCursorShell::Right(nRedlineLength, CRSR_SKIP_CHARS); - bRet = Delete(); + bRet = Delete(false); CloseMark( bRet ); } else @@ -560,7 +560,7 @@ void SwWrtShell::DelToEndOfPara() Pop(SwCursorShell::PopMode::DeleteCurrent); return; } - bool bRet = Delete(); + bool bRet = Delete(false); Pop(SwCursorShell::PopMode::DeleteCurrent); if( bRet ) UpdateAttr(); @@ -577,7 +577,7 @@ void SwWrtShell::DelToStartOfPara() Pop(SwCursorShell::PopMode::DeleteCurrent); return; } - bool bRet = Delete(); + bool bRet = Delete(false); Pop(SwCursorShell::PopMode::DeleteCurrent); if( bRet ) UpdateAttr(); @@ -592,7 +592,7 @@ void SwWrtShell::DelToStartOfSentence() if(IsStartOfDoc()) return; OpenMark(); - bool bRet = BwdSentence_() && Delete(); + bool bRet = BwdSentence_() && Delete(false); CloseMark( bRet ); } @@ -624,7 +624,7 @@ bool SwWrtShell::DelToEndOfSentence() } else { - bRet = FwdSentence_() && Delete(); + bRet = FwdSentence_() && Delete(false); } CloseMark( bRet ); return bRet; @@ -645,7 +645,7 @@ void SwWrtShell::DelNxtWord() else EndWrd(); - bool bRet = Delete(); + bool bRet = Delete(false); if( bRet ) UpdateAttr(); else @@ -669,7 +669,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); } }