[PATCH v2 3/3] riched20: implement ITextRange::StartOf() and ITextRange::EndOf() for tomCharacter
Damjan Jovanovic
damjan.jov at gmail.com
Tue Aug 18 22:19:52 CDT 2020
Signed-off-by: Damjan Jovanovic <damjan.jov at gmail.com>
---
dlls/riched20/richole.c | 100 +++++++++++++++++++++++++++++++---
dlls/riched20/tests/richole.c | 64 ++++++++++++++++++++++
2 files changed, 156 insertions(+), 8 deletions(-)
-------------- next part --------------
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c
index c7a84b6e78..47d8442d5c 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -2153,17 +2153,91 @@ static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
return S_OK;
}
+static HRESULT textrange_startof(ITextRange *range, LONG unit, LONG extend, LONG *delta)
+{
+ HRESULT hr;
+ LONG start, end;
+ LONG moved;
+
+ ITextRange_GetStart(range, &start);
+ ITextRange_GetEnd(range, &end);
+
+ switch (unit)
+ {
+ case tomCharacter:
+ {
+ moved = 0;
+ if (extend == tomMove) {
+ if (start != end) {
+ ITextRange_SetEnd(range, start);
+ moved = -1;
+ }
+ }
+ if (delta)
+ *delta = moved;
+ hr = moved ? S_OK : S_FALSE;
+ break;
+ }
+ default:
+ FIXME("unit %d is not supported\n", unit);
+ return E_NOTIMPL;
+ }
+ return hr;
+}
+
static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
LONG *delta)
{
ITextRangeImpl *This = impl_from_ITextRange(me);
- FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
+ TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
if (!This->child.reole)
return CO_E_RELEASED;
- return E_NOTIMPL;
+ return textrange_startof(me, unit, extend, delta);
+}
+
+static HRESULT textrange_endof(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG extend, LONG *delta)
+{
+ HRESULT hr;
+ LONG old_start, old_end, new_end;
+ LONG moved;
+
+ ITextRange_GetStart(range, &old_start);
+ ITextRange_GetEnd(range, &old_end);
+
+ switch (unit)
+ {
+ case tomCharacter:
+ {
+ moved = 0;
+ new_end = old_end;
+ if (old_end == 0) {
+ ME_Cursor cursor;
+ ME_CursorFromCharOfs(editor, old_end, &cursor);
+ moved = ME_MoveCursorChars(editor, &cursor, 1, TRUE);
+ new_end = old_end + moved;
+ } else {
+ if (extend == tomMove) {
+ if (old_start != old_end) {
+ moved = 1;
+ }
+ }
+ }
+ ITextRange_SetEnd(range, new_end);
+ if (extend == tomMove)
+ ITextRange_SetStart(range, new_end);
+ if (delta)
+ *delta = moved;
+ hr = moved ? S_OK : S_FALSE;
+ break;
+ }
+ default:
+ FIXME("unit %d is not supported\n", unit);
+ return E_NOTIMPL;
+ }
+ return hr;
}
static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
@@ -2171,12 +2245,12 @@ static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend,
{
ITextRangeImpl *This = impl_from_ITextRange(me);
- FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
+ TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
if (!This->child.reole)
return CO_E_RELEASED;
- return E_NOTIMPL;
+ return textrange_endof(me, This->child.reole->editor, unit, extend, delta);
}
static HRESULT textrange_move(ITextRange *range, ME_TextEditor *editor, LONG unit, LONG count, LONG *delta)
@@ -5064,26 +5138,36 @@ static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LO
LONG *delta)
{
ITextSelectionImpl *This = impl_from_ITextSelection(me);
+ ITextRange *range = NULL;
+ HRESULT hr;
- FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
+ TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
if (!This->reOle)
return CO_E_RELEASED;
- return E_NOTIMPL;
+ ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
+ hr = textrange_startof(range, unit, extend, delta);
+ ITextRange_Release(range);
+ return hr;
}
static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
LONG *delta)
{
ITextSelectionImpl *This = impl_from_ITextSelection(me);
+ ITextRange *range = NULL;
+ HRESULT hr;
- FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
+ TRACE("(%p)->(%d %d %p)\n", This, unit, extend, delta);
if (!This->reOle)
return CO_E_RELEASED;
- return E_NOTIMPL;
+ ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range);
+ hr = textrange_endof(range, This->reOle->editor, unit, extend, delta);
+ ITextRange_Release(range);
+ return hr;
}
static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c
index 7fde2ca232..16ff1fafa6 100644
--- a/dlls/riched20/tests/richole.c
+++ b/dlls/riched20/tests/richole.c
@@ -3912,6 +3912,68 @@ static void test_character_move(ITextRange *range, int textlen, int i, int j, LO
}
}
+static void test_character_startof(ITextRange *range, int textlen, int i, int j)
+{
+ HRESULT hr;
+ LONG delta;
+
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_StartOf(range, tomCharacter, tomMove, &delta);
+ if (i == j) {
+ ok(hr == S_FALSE, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
+ ok(delta == 0, "(%d,%d) tomMove got delta %d\n", i, j, delta);
+ } else {
+ ok(hr == S_OK, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
+ ok(delta == -1, "(%d,%d) tomMove got delta %d\n", i, j, delta);
+ }
+ CHECK_RANGE(range, i, i);
+
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_StartOf(range, tomCharacter, tomExtend, &delta);
+ ok(hr == S_FALSE, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr);
+ ok(delta == 0, "(%d,%d) tomExtend got delta %d\n", i, j, delta);
+ CHECK_RANGE(range, i, j);
+}
+
+static void test_character_endof(ITextRange *range, int textlen, int i, int j)
+{
+ HRESULT hr;
+ LONG end;
+ LONG delta;
+
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_EndOf(range, tomCharacter, tomMove, &delta);
+
+ /* A character "end", apparently cannot be before the very first character */
+ end = j;
+ if (j == 0)
+ ++end;
+
+ if (i == end) {
+ ok(hr == S_FALSE, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
+ ok(delta == 0, "(%d,%d) tomMove got delta %d\n", i, j, delta);
+ } else {
+ ok(hr == S_OK, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
+ ok(delta == 1, "(%d,%d) tomMove got delta %d\n", i, j, delta);
+ }
+ CHECK_RANGE(range, end, end);
+
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_EndOf(range, tomCharacter, tomExtend, &delta);
+ if (0 < j) {
+ ok(hr == S_FALSE, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr);
+ ok(delta == 0, "(%d,%d) tomExtend got delta %d\n", i, j, delta);
+ } else {
+ ok(hr == S_OK, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr);
+ ok(delta == 1, "(%d,%d) tomExtend got delta %d\n", i, j, delta);
+ }
+ CHECK_RANGE(range, i, end);
+}
+
static void test_character_movement(void)
{
static const char test_text1[] = "ab\n c";
@@ -3940,6 +4002,8 @@ static void test_character_movement(void)
test_character_movestart(range, textlen, i, j, target);
test_character_move(range, textlen, i, j, target);
}
+ test_character_startof(range, textlen, i, j);
+ test_character_endof(range, textlen, i, j);
}
}
More information about the wine-devel
mailing list