riched20: Implement ITextRange::StartOf() and ITextRange::EndOf() for tomCharacter.
Signed-off-by: Damjan Jovanovic <damjan.jov@gmail.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
55d4cf27af
commit
7a347c20dc
|
@ -2153,17 +2153,91 @@ static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me)
|
||||||
return S_OK;
|
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,
|
static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend,
|
||||||
LONG *delta)
|
LONG *delta)
|
||||||
{
|
{
|
||||||
ITextRangeImpl *This = impl_from_ITextRange(me);
|
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)
|
if (!This->child.reole)
|
||||||
return CO_E_RELEASED;
|
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,
|
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);
|
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)
|
if (!This->child.reole)
|
||||||
return CO_E_RELEASED;
|
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)
|
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)
|
LONG *delta)
|
||||||
{
|
{
|
||||||
ITextSelectionImpl *This = impl_from_ITextSelection(me);
|
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)
|
if (!This->reOle)
|
||||||
return CO_E_RELEASED;
|
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,
|
static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend,
|
||||||
LONG *delta)
|
LONG *delta)
|
||||||
{
|
{
|
||||||
ITextSelectionImpl *This = impl_from_ITextSelection(me);
|
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)
|
if (!This->reOle)
|
||||||
return CO_E_RELEASED;
|
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)
|
static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta)
|
||||||
|
|
|
@ -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 void test_character_movement(void)
|
||||||
{
|
{
|
||||||
static const char test_text1[] = "ab\n c";
|
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_movestart(range, textlen, i, j, target);
|
||||||
test_character_move(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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue