summaryrefslogtreecommitdiff
path: root/editeng
diff options
context:
space:
mode:
authorJustin Luth <jluth@mail.com>2023-11-02 13:35:24 -0400
committerJustin Luth <jluth@mail.com>2023-11-15 20:03:28 +0100
commit213c6a9999e84f084978391c16276017078bf9ed (patch)
tree4a7750b860ed2cb877576fe4801b243c2295184b /editeng
parent861ebce9ca52cbe87121879f159d8ec0cb572755 (diff)
related tdf#158031 editeng: GetFieldAtSel...(+look before cursor)
Nearly a No-Functional-Change, but not quite. For practical and intentional purposes, it can be considered NFC. Although I didn't find an actual case where it happened, a code read says SelectFieldAtCursor COULD select a non-field. It assumed that previous code had already identified that there must be a field here. Well, I want to extend GetFieldAtSelection to check backwards to solve bug 158031 anyway, so I might as well "fix" this assumption to only select a valid field. This function REALLY depends on GetFieldAtSelection working properly. So, I put some asserts in to ensure that stays true. Change-Id: Ie22945a418497511501b04df5e17071d977cbd5b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158855 Tested-by: Jenkins Reviewed-by: Justin Luth <jluth@mail.com>
Diffstat (limited to 'editeng')
-rw-r--r--editeng/source/editeng/editview.cxx59
1 files changed, 42 insertions, 17 deletions
diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx
index d73cb24ef452..bfa98d1ae702 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -1344,7 +1344,16 @@ const SvxFieldItem* EditView::GetFieldUnderMousePointer( sal_Int32& nPara, sal_I
return GetField( aPos, &nPara, &nPos );
}
-const SvxFieldItem* EditView::GetFieldAtSelection() const
+const SvxFieldItem* EditView::GetFieldAtSelection(bool bAlsoCheckBeforeCursor) const
+{
+ bool* pIsBeforeCursor = bAlsoCheckBeforeCursor ? &bAlsoCheckBeforeCursor : nullptr;
+ return GetFieldAtSelection(pIsBeforeCursor);
+}
+
+// If pIsBeforeCursor != nullptr, the position before the cursor will also be checked for a field
+// and pIsBeforeCursor will return true if that fallback field is returned.
+// If no field is returned, the value in pIsBeforeCursor is meaningless.
+const SvxFieldItem* EditView::GetFieldAtSelection(bool* pIsBeforeCursor) const
{
// a field is a dummy character - so it cannot span nodes or be a selection larger than 1
EditSelection aSel( pImpEditView->GetEditSelection() );
@@ -1361,6 +1370,13 @@ const SvxFieldItem* EditView::GetFieldAtSelection() const
// Only when cursor is in font of field, no selection,
// or only selecting field
+ bool bAlsoCheckBeforeCursor = false;
+ if (pIsBeforeCursor)
+ {
+ *pIsBeforeCursor = false;
+ bAlsoCheckBeforeCursor = nMaxIndex == nMinIndex;
+ }
+ const SvxFieldItem* pFoundBeforeCursor = nullptr;
const CharAttribList::AttribsType& rAttrs = aSel.Min().GetNode()->GetCharAttribs().GetAttribs();
for (const auto& rAttr: rAttrs)
{
@@ -1369,34 +1385,43 @@ const SvxFieldItem* EditView::GetFieldAtSelection() const
DBG_ASSERT(dynamic_cast<const SvxFieldItem*>(rAttr->GetItem()), "No FieldItem...");
if (rAttr->GetStart() == nMinIndex)
return static_cast<const SvxFieldItem*>(rAttr->GetItem());
+
+ // perhaps the cursor is behind the field?
+ if (nMinIndex && rAttr->GetStart() == nMinIndex - 1)
+ pFoundBeforeCursor = static_cast<const SvxFieldItem*>(rAttr->GetItem());
}
}
+ if (bAlsoCheckBeforeCursor)
+ {
+ *pIsBeforeCursor = /*(bool)*/pFoundBeforeCursor;
+ return pFoundBeforeCursor;
+ }
return nullptr;
}
void EditView::SelectFieldAtCursor()
{
- const SvxFieldItem* pFieldItem = GetFieldAtSelection();
- if (pFieldItem)
- {
- // Make sure the whole field is selected
- ESelection aSel = GetSelection();
- if (aSel.nStartPos == aSel.nEndPos)
- {
- aSel.nEndPos++;
- SetSelection(aSel);
- }
- }
+ bool bIsBeforeCursor = false;
+ const SvxFieldItem* pFieldItem = GetFieldAtSelection(&bIsBeforeCursor);
if (!pFieldItem)
+ return;
+
+ // Make sure the whole field is selected
+ // A field is represented by a dummy character - so it cannot be a selection larger than 1
+ ESelection aSel = GetSelection();
+ if (aSel.nStartPos == aSel.nEndPos) // not yet selected
{
- // Cursor probably behind the field - extend selection to select the field
- ESelection aSel = GetSelection();
- if (aSel.nStartPos > 0 && aSel.nStartPos == aSel.nEndPos)
+ if (bIsBeforeCursor)
{
- aSel.nStartPos--;
- SetSelection(aSel);
+ assert (aSel.nStartPos);
+ --aSel.nStartPos;
}
+ else
+ aSel.nEndPos++;
+ SetSelection(aSel);
}
+ else
+ assert(std::abs(aSel.nStartPos - aSel.nEndPos) == 1);
}
const SvxFieldData* EditView::GetFieldAtCursor() const