summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2022-07-22 19:34:12 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2022-07-27 18:39:27 +0200
commitbaf8d2c1c16cb3bdc4edad2560f95fea807a034f (patch)
treed2c2cb27364cbaf0e517a22edb3fc28923f888a4
parent316e4c01f4056242b82047808169c78692a3d9e3 (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
-rw-r--r--sw/inc/unobaseclass.hxx19
-rw-r--r--sw/inc/unotextcursor.hxx4
-rw-r--r--sw/inc/unotextrange.hxx2
-rw-r--r--sw/source/core/undo/undel.cxx1
-rw-r--r--sw/source/core/undo/undobj.cxx7
-rw-r--r--sw/source/core/unocore/unoobj.cxx11
-rw-r--r--sw/source/core/unocore/unoobj2.cxx9
-rw-r--r--sw/source/core/unocore/unotext.cxx22
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();