From: Nikolay Sivov Subject: [PATCH 2/5] riched20: Implement Start/End properties for ranges (try2) Message-Id: <5561E547.60207@codeweavers.com> Date: Sun, 24 May 2015 17:50:47 +0300 --- From 3e51dbb4668a619f6bfc95d03e4bf323dfb60142 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sun, 24 May 2015 14:08:16 +0300 Subject: [PATCH 2/5] riched20: Implement Start/End properties for ranges --- dlls/riched20/richole.c | 120 +++++++++++++++++---------- dlls/riched20/tests/richole.c | 189 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 258 insertions(+), 51 deletions(-) diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c index 9ae6b0f..af140f5 100644 --- a/dlls/riched20/richole.c +++ b/dlls/riched20/richole.c @@ -1229,89 +1229,99 @@ static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange * return E_NOTIMPL; } -static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *pcpFirst) +static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start) { ITextRangeImpl *This = impl_from_ITextRange(me); + + TRACE("(%p)->(%p)\n", This, start); + if (!This->reOle) return CO_E_RELEASED; - if (!pcpFirst) + if (!start) return E_INVALIDARG; - *pcpFirst = This->start; - TRACE("%d\n", *pcpFirst); + + *start = This->start; return S_OK; } -static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG start) +static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end) { - ITextRangeImpl *This = impl_from_ITextRange(me); int len; - TRACE("(%p)->(%d)\n", This, start); + if (value < 0) + value = 0; - if (!This->reOle) - return CO_E_RELEASED; - - if (start == This->start) + if (value == *start) return S_FALSE; - if (start < 0) { - This->start = 0; + if (value <= *end) { + *start = value; return S_OK; } - len = ME_GetTextLength(This->reOle->editor); - if (start > This->end) - This->end = len; - - if (start > len) - This->start = len; - else - This->start = start; - + len = ME_GetTextLength(reole->editor); + *start = *end = value > len ? len : value; return S_OK; } -static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *pcpLim) +static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value) { ITextRangeImpl *This = impl_from_ITextRange(me); + + TRACE("(%p)->(%d)\n", This, value); + if (!This->reOle) return CO_E_RELEASED; - if (!pcpLim) - return E_INVALIDARG; - *pcpLim = This->end; - TRACE("%d\n", *pcpLim); - return S_OK; + return textrange_setstart(This->reOle, value, &This->start, &This->end); } -static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG end) +static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end) { ITextRangeImpl *This = impl_from_ITextRange(me); - int len; - TRACE("(%p)->(%d)\n", This, end); + TRACE("(%p)->(%p)\n", This, end); if (!This->reOle) return CO_E_RELEASED; - if (end == This->end) + if (!end) + return E_INVALIDARG; + + *end = This->end; + return S_OK; +} + +static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end) +{ + int len; + + if (value == *end) return S_FALSE; - if (end < This->start) { - This->start = This->end = max(0, end); + if (value < *start) { + *start = *end = max(0, value); return S_OK; } - len = ME_GetTextLength(This->reOle->editor); - if (end > len) - This->end = len + 1; - else - This->end = end; - + len = ME_GetTextLength(reole->editor); + *end = value > len ? len + 1 : value; return S_OK; } +static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + + TRACE("(%p)->(%d)\n", This, value); + + if (!This->reOle) + return CO_E_RELEASED; + + return textrange_setend(This->reOle, value, &This->start, &This->end); +} + static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font) { ITextRangeImpl *This = impl_from_ITextRange(me); @@ -3454,14 +3464,23 @@ static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFir return S_OK; } -static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG cpFirst) +static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value) { ITextSelectionImpl *This = impl_from_ITextSelection(me); + LONG start, end; + HRESULT hr; + + TRACE("(%p)->(%d)\n", This, value); + if (!This->reOle) return CO_E_RELEASED; - FIXME("not implemented\n"); - return E_NOTIMPL; + ME_GetSelectionOfs(This->reOle->editor, &start, &end); + hr = textrange_setstart(This->reOle, value, &start, &end); + if (hr == S_OK) + ME_SetSelection(This->reOle->editor, start, end); + + return hr; } static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim) @@ -3478,14 +3497,23 @@ static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim) return S_OK; } -static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG cpLim) +static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value) { ITextSelectionImpl *This = impl_from_ITextSelection(me); + LONG start, end; + HRESULT hr; + + TRACE("(%p)->(%d)\n", This, value); + if (!This->reOle) return CO_E_RELEASED; - FIXME("not implemented\n"); - return E_NOTIMPL; + ME_GetSelectionOfs(This->reOle->editor, &start, &end); + hr = textrange_setend(This->reOle, value, &start, &end); + if (hr == S_OK) + ME_SetSelection(This->reOle->editor, start, end); + + return hr; } static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font) diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c index 6a5b899..95a4e05 100644 --- a/dlls/riched20/tests/richole.c +++ b/dlls/riched20/tests/richole.c @@ -749,16 +749,29 @@ static void test_ITextRange_GetStart_GetEnd(void) hres = ITextRange_SetStart(txtRge, 1); ok(hres == S_OK, "got 0x%08x\n", hres); - /* negative resets to 0 */ + /* negative resets to 0, return value is S_FALSE when + position wasn't changed */ hres = ITextRange_SetStart(txtRge, -1); ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextRange_SetStart(txtRge, -1); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + hres = ITextRange_SetStart(txtRge, 0); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + start = -1; hres = ITextRange_GetStart(txtRge, &start); ok(hres == S_OK, "got 0x%08x\n", hres); ok(start == 0, "got %d\n", start); /* greater than initial end, but less than total char count */ + hres = ITextRange_SetStart(txtRge, 1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextRange_SetEnd(txtRge, 3); + ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextRange_SetStart(txtRge, 10); ok(hres == S_OK, "got 0x%08x\n", hres); @@ -770,8 +783,9 @@ static void test_ITextRange_GetStart_GetEnd(void) end = 0; hres = ITextRange_GetEnd(txtRge, &end); ok(hres == S_OK, "got 0x%08x\n", hres); - ok(end == 12, "got %d\n", end); + ok(end == 10, "got %d\n", end); + /* more that total text length */ hres = ITextRange_SetStart(txtRge, 50); ok(hres == S_OK, "got 0x%08x\n", hres); @@ -855,9 +869,28 @@ static void test_ITextRange_GetStart_GetEnd(void) ok(hres == S_OK, "got 0x%08x\n", hres); ok(end == 0, "got %d\n", end); - ITextRange_Release(txtRge); - release_interfaces(&w, &reOle, &txtDoc, NULL); + + /* detached range */ + hres = ITextRange_SetStart(txtRge, 0); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_SetEnd(txtRge, 3); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetStart(txtRge, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetEnd(txtRge, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + ITextRange_Release(txtRge); } static void test_ITextSelection_GetStart_GetEnd(void) @@ -917,7 +950,153 @@ static void test_ITextSelection_GetStart_GetEnd(void) ok(hres == S_OK, "ITextSelection_GetEnd\n"); ok(end == 12, "got wrong end value: %d\n", end); - release_interfaces(&w, &reOle, &txtDoc, &txtSel); + /* SetStart/SetEnd */ + hres = ITextSelection_SetStart(txtSel, 0); + ok(hres == S_OK, "got 0x%08x\n", hres); + + /* same value */ + hres = ITextSelection_SetStart(txtSel, 0); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + hres = ITextSelection_SetStart(txtSel, 1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + /* negative resets to 0, return value is S_FALSE when + position wasn't changed */ + hres = ITextSelection_SetStart(txtSel, -1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextSelection_SetStart(txtSel, -1); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + hres = ITextSelection_SetStart(txtSel, 0); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + start = -1; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 0, "got %d\n", start); + + /* greater than initial end, but less than total char count */ + hres = ITextSelection_SetStart(txtSel, 1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextSelection_SetEnd(txtSel, 3); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextSelection_SetStart(txtSel, 10); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 10, "got %d\n", start); + + end = 0; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 10, "got %d\n", end); + + /* more that total text length */ + hres = ITextSelection_SetStart(txtSel, 50); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 12, "got %d\n", start); + + end = 0; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 12, "got %d\n", end); + + /* SetEnd */ + hres = ITextSelection_SetStart(txtSel, 0); + ok(hres == S_OK, "got 0x%08x\n", hres); + + /* same value */ + hres = ITextSelection_SetEnd(txtSel, 5); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextSelection_SetEnd(txtSel, 5); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + /* negative resets to 0 */ + hres = ITextSelection_SetEnd(txtSel, -1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + end = -1; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 0, "got %d\n", end); + + start = -1; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 0, "got %d\n", start); + + /* greater than initial end, but less than total char count */ + hres = ITextSelection_SetStart(txtSel, 3); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextSelection_SetEnd(txtSel, 1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 1, "got %d\n", start); + + end = 0; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 1, "got %d\n", end); + + /* more than total count */ + hres = ITextSelection_SetEnd(txtSel, 50); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 1, "got %d\n", start); + + end = 0; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 13, "got %d\n", end); + + /* zero */ + hres = ITextSelection_SetEnd(txtSel, 0); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 0, "got %d\n", start); + + end = 0; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 0, "got %d\n", end); + + release_interfaces(&w, &reOle, &txtDoc, NULL); + + /* detached selection */ + hres = ITextSelection_GetStart(txtSel, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextSelection_GetEnd(txtSel, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + ITextSelection_Release(txtSel); } static void test_ITextRange_GetDuplicate(void) -- 2.1.4