diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2022-07-22 19:34:12 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2022-07-27 18:39:27 +0200 |
commit | baf8d2c1c16cb3bdc4edad2560f95fea807a034f (patch) | |
tree | d2c2cb27364cbaf0e517a22edb3fc28923f888a4 /sw | |
parent | 316e4c01f4056242b82047808169c78692a3d9e3 (diff) |
sw: delete bookmark if paragraph is fully selected
testTdf96479 requires inserting with absorb=true to be treated as
Replace, and there is of course no string in insertTextContent().
testDeleteFlyAtCharAtStart requires setString("") to be treated as
Delete.
Annoyingly this requires API setString() call to be replaced with
internal call, do this for SwXTextRange and SwXTextCursor which are
the 2 classes typically used in practice.
Change-Id: I87caa1aa11abe298cdd3d9a9bbb602e547c7b443
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137370
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/unobaseclass.hxx | 19 | ||||
-rw-r--r-- | sw/inc/unotextcursor.hxx | 4 | ||||
-rw-r--r-- | sw/inc/unotextrange.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/undo/undel.cxx | 1 | ||||
-rw-r--r-- | sw/source/core/undo/undobj.cxx | 7 | ||||
-rw-r--r-- | sw/source/core/unocore/unoobj.cxx | 11 | ||||
-rw-r--r-- | sw/source/core/unocore/unoobj2.cxx | 9 | ||||
-rw-r--r-- | sw/source/core/unocore/unotext.cxx | 22 |
8 files changed, 59 insertions, 16 deletions
diff --git a/sw/inc/unobaseclass.hxx b/sw/inc/unobaseclass.hxx index 049d28b9a748..8635d47c5f8f 100644 --- a/sw/inc/unobaseclass.hxx +++ b/sw/inc/unobaseclass.hxx @@ -24,6 +24,9 @@ #include <com/sun/star/container/XEnumeration.hpp> #include <cppuhelper/implbase.hxx> + +#include <o3tl/typed_flags_set.hxx> + #include <vcl/svapp.hxx> class SfxPoolItem; @@ -53,6 +56,22 @@ enum class CursorType ContentControl, }; +namespace sw { + +enum class DeleteAndInsertMode +{ + Default = 0, + ForceExpandHints = (1<<0), + ForceReplace = (1<<1), +}; + +} // namespace sw + +namespace o3tl +{ + template<> struct typed_flags<::sw::DeleteAndInsertMode> : is_typed_flags<::sw::DeleteAndInsertMode, 0x03> {}; +} + /* Start/EndAction or Start/EndAllAction */ diff --git a/sw/inc/unotextcursor.hxx b/sw/inc/unotextcursor.hxx index b055f2d64504..f3bf0a24dcfe 100644 --- a/sw/inc/unotextcursor.hxx +++ b/sw/inc/unotextcursor.hxx @@ -102,9 +102,7 @@ public: bool IsAtEndOfMeta() const; bool IsAtEndOfContentControl() const; - void DeleteAndInsert(OUString const& rText, - const bool bForceExpandHints); - + void DeleteAndInsert(OUString const& rText, ::sw::DeleteAndInsertMode eMode); // OTextCursorHelper virtual const SwPaM* GetPaM() const override; virtual SwPaM* GetPaM() override; diff --git a/sw/inc/unotextrange.hxx b/sw/inc/unotextrange.hxx index 4d8ed2df2c06..b4862b7f6523 100644 --- a/sw/inc/unotextrange.hxx +++ b/sw/inc/unotextrange.hxx @@ -109,7 +109,7 @@ private: //TODO: new exception type for protected content /// @throws css::uno::RuntimeException void DeleteAndInsert( - const OUString& rText, const bool bForceExpandHints); + const OUString& rText, ::sw::DeleteAndInsertMode eMode); void Invalidate(); virtual ~SwXTextRange() override; diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx index d85ea6e83389..0ccb11526bb6 100644 --- a/sw/source/core/undo/undel.cxx +++ b/sw/source/core/undo/undel.cxx @@ -1306,6 +1306,7 @@ void SwUndoDelete::RedoImpl(::sw::UndoRedoContext & rContext) rDoc.getIDocumentContentOperations().DelFullPara( rPam ); } else + // FIXME: this ends up calling DeleteBookmarks() on the entire rPam which deletes too many! rDoc.getIDocumentContentOperations().DeleteAndJoin(rPam, m_DeleteFlags); } diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx index 88600fada374..401dab1ec648 100644 --- a/sw/source/core/undo/undobj.cxx +++ b/sw/source/core/undo/undobj.cxx @@ -1136,7 +1136,12 @@ void SwUndoSaveContent::DelContentIndex( const SwPosition& rMark, && ( type == IDocumentMarkAccess::MarkType::TEXT_FIELDMARK || type == IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK || type == IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK - || type == IDocumentMarkAccess::MarkType::DATE_FIELDMARK))) + || type == IDocumentMarkAccess::MarkType::DATE_FIELDMARK)) + || (bMaybe + && !(nDelContentType & DelContentType::Replace) + && type == IDocumentMarkAccess::MarkType::BOOKMARK + && pStt->nContent == 0 // entire paragraph deleted? + && pEnd->nContent == pEnd->nNode.GetNode().GetTextNode()->Len())) { if( bMaybe ) bSavePos = true; diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx index 394534b6c8f6..87ab9acc6141 100644 --- a/sw/source/core/unocore/unoobj.cxx +++ b/sw/source/core/unocore/unoobj.cxx @@ -705,7 +705,7 @@ SwXTextCursor::~SwXTextCursor() } void SwXTextCursor::DeleteAndInsert(const OUString& rText, - const bool bForceExpandHints) + ::sw::DeleteAndInsertMode const eMode) { auto pUnoCursor = static_cast<SwCursor*>(m_pUnoCursor.get()); if (!pUnoCursor) @@ -721,13 +721,16 @@ void SwXTextCursor::DeleteAndInsert(const OUString& rText, { if (pCurrent->HasMark()) { - rDoc.getIDocumentContentOperations().DeleteAndJoin(*pCurrent); + rDoc.getIDocumentContentOperations().DeleteAndJoin(*pCurrent, + // is it "delete" or "replace"? + // FIXME still test failure because insertTextContent calls with empty string + (nTextLen != 0 || eMode & ::sw::DeleteAndInsertMode::ForceReplace) ? SwDeleteFlags::ArtificialSelection : SwDeleteFlags::Default); } if(nTextLen) { const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR( - rDoc, *pCurrent, rText, bForceExpandHints ) ); + rDoc, *pCurrent, rText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints))); OSL_ENSURE( bSuccess, "Doc->Insert(Str) failed." ); SwUnoCursorHelper::SelectPam(*pUnoCursor, true); @@ -1724,7 +1727,7 @@ SwXTextCursor::setString(const OUString& aString) const bool bForceExpandHints( (CursorType::Meta == m_eType) && dynamic_cast<SwXMeta&>(*m_xParentText) .CheckForOwnMemberMeta(*GetPaM(), true) ); - DeleteAndInsert(aString, bForceExpandHints); + DeleteAndInsert(aString, bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default); } uno::Any SwUnoCursorHelper::GetPropertyValue( diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx index d0dc4d34f8e9..226944083aef 100644 --- a/sw/source/core/unocore/unoobj2.cxx +++ b/sw/source/core/unocore/unoobj2.cxx @@ -800,7 +800,7 @@ static void DeleteTable(SwDoc & rDoc, SwTable& rTable) } void SwXTextRange::DeleteAndInsert( - const OUString& rText, const bool bForceExpandHints) + const OUString& rText, ::sw::DeleteAndInsertMode const eMode) { if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) { @@ -887,13 +887,14 @@ void SwXTextRange::DeleteAndInsert( if (aCursor.HasMark()) { - m_pImpl->m_rDoc.getIDocumentContentOperations().DeleteAndJoin(aCursor); + m_pImpl->m_rDoc.getIDocumentContentOperations().DeleteAndJoin(aCursor, + (!rText.isEmpty() || eMode & ::sw::DeleteAndInsertMode::ForceReplace) ? SwDeleteFlags::ArtificialSelection : SwDeleteFlags::Default); } if (!rText.isEmpty()) { SwUnoCursorHelper::DocInsertStringSplitCR( - m_pImpl->m_rDoc, aCursor, rText, bForceExpandHints); + m_pImpl->m_rDoc, aCursor, rText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints)); SwUnoCursorHelper::SelectPam(aCursor, true); aCursor.Left(rText.getLength()); @@ -1060,7 +1061,7 @@ void SAL_CALL SwXTextRange::setString(const OUString& rString) { SolarMutexGuard aGuard; - DeleteAndInsert(rString, false); + DeleteAndInsert(rString, ::sw::DeleteAndInsertMode::Default); } bool SwXTextRange::GetPositions(SwPaM& rToFill, ::sw::TextRangeMode const eMode) const diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx index bcef9e4db57c..c12ed195d137 100644 --- a/sw/source/core/unocore/unotext.cxx +++ b/sw/source/core/unocore/unotext.cxx @@ -364,7 +364,8 @@ SwXText::insertString(const uno::Reference< text::XTextRange >& xTextRange, dynamic_cast<SwXTextCursor*>(pCursor) ); if (pTextCursor) { - pTextCursor->DeleteAndInsert(rString, bForceExpandHints); + pTextCursor->DeleteAndInsert(rString, ::sw::DeleteAndInsertMode::ForceReplace + | (bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default)); } else { @@ -373,7 +374,8 @@ SwXText::insertString(const uno::Reference< text::XTextRange >& xTextRange, } else { - pRange->DeleteAndInsert(rString, bForceExpandHints); + pRange->DeleteAndInsert(rString, ::sw::DeleteAndInsertMode::ForceReplace + | (bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default)); } } else @@ -606,7 +608,21 @@ SwXText::insertTextContent( if (bAbsorb && !bAttribute) { - xRange->setString(OUString()); + uno::Reference<lang::XUnoTunnel> const xRangeTunnel(xRange, uno::UNO_QUERY); + if (SwXTextRange *const pRange = comphelper::getFromUnoTunnel<SwXTextRange>(xRangeTunnel)) + { + pRange->DeleteAndInsert(OUString(), ::sw::DeleteAndInsertMode::ForceReplace + | (bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default)); + } + else if (SwXTextCursor *const pCursor = dynamic_cast<SwXTextCursor*>(comphelper::getFromUnoTunnel<OTextCursorHelper>(xRangeTunnel))) + { + pCursor->DeleteAndInsert(OUString(), ::sw::DeleteAndInsertMode::ForceReplace + | (bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default)); + } + else + { + xRange->setString(OUString()); + } } uno::Reference< text::XTextRange > xTempRange = (bAttribute && bAbsorb) ? xRange : xRange->getStart(); |