riched20: Implement SetText for regular range.

This commit is contained in:
Nikolay Sivov 2015-05-27 00:45:25 +03:00 committed by Alexandre Julliard
parent aa37c179ad
commit d27234617c
2 changed files with 157 additions and 3 deletions

View file

@ -201,6 +201,10 @@ typedef union {
BSTR str;
} textfont_prop_val;
enum range_update_op {
RANGE_UPDATE_DELETE
};
typedef struct IRichEditOleImpl {
IUnknown IUnknown_inner;
IRichEditOle IRichEditOle_iface;
@ -304,6 +308,35 @@ static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface)
static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**);
static HRESULT create_textpara(ITextRange*, ITextPara**);
static void textranges_update_ranges(IRichEditOleImpl *reole, LONG start, LONG end, enum range_update_op op)
{
ITextRangeImpl *range;
LIST_FOR_EACH_ENTRY(range, &reole->rangelist, ITextRangeImpl, entry) {
switch (op)
{
case RANGE_UPDATE_DELETE:
/* range fully covered by deleted range - collapse to insertion point */
if (range->start >= start && range->end <= end)
range->start = range->end = start;
/* deleted range cuts from the right */
else if (range->start < start && range->end <= end)
range->end = start;
/* deleted range cuts from the left */
else if (range->start >= start && range->end > end) {
range->start = start;
range->end -= end - start;
}
/* deleted range cuts within */
else
range->end -= end - start;
break;
default:
FIXME("unknown update op, %d\n", op);
}
}
}
static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left,
textfont_prop_val *right)
{
@ -1376,14 +1409,48 @@ static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *pbstr)
return E_NOTIMPL;
}
static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR bstr)
static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str)
{
ITextRangeImpl *This = impl_from_ITextRange(me);
ME_TextEditor *editor;
ME_Cursor cursor;
ME_Style *style;
int len;
TRACE("(%p)->(%s)\n", This, debugstr_w(str));
if (!This->reOle)
return CO_E_RELEASED;
FIXME("not implemented %p\n", This);
return E_NOTIMPL;
editor = This->reOle->editor;
/* delete only where's something to delete */
if (This->start != This->end) {
ME_CursorFromCharOfs(editor, This->start, &cursor);
ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
}
if (!str || !*str) {
/* will update this range as well */
textranges_update_ranges(This->reOle, This->start, This->end, RANGE_UPDATE_DELETE);
return S_OK;
}
/* it's safer not to rely on stored BSTR length */
len = strlenW(str);
cursor = editor->pCursors[0];
ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]);
style = ME_GetInsertStyle(editor, 0);
ME_InsertTextFromCursor(editor, 0, str, len, style);
ME_ReleaseStyle(style);
editor->pCursors[0] = cursor;
if (len < This->end - This->start)
textranges_update_ranges(This->reOle, This->start + len, This->end, RANGE_UPDATE_DELETE);
else
This->end = len - This->start;
return S_OK;
}
static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch)

View file

@ -2401,6 +2401,92 @@ todo_wine
release_interfaces(&hwnd, &reOle, &doc, NULL);
}
static void test_SetText(void)
{
static const CHAR test_text1[] = "TestSomeText";
static const WCHAR textW[] = {'a','b','c','d','e','f','g','h','i',0};
IRichEditOle *reOle = NULL;
ITextDocument *doc = NULL;
ITextRange *range, *range2;
LONG value;
HRESULT hr;
HWND hwnd;
BSTR str;
create_interfaces(&hwnd, &reOle, &doc, NULL);
SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
hr = ITextDocument_Range(doc, 0, 4, &range);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = ITextDocument_Range(doc, 0, 4, &range2);
ok(hr == S_OK, "got 0x%08x\n", hr);
value = 1;
hr = ITextRange_GetStart(range2, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 0, "got %d\n", value);
value = 0;
hr = ITextRange_GetEnd(range2, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 4, "got %d\n", value);
hr = ITextRange_SetText(range, NULL);
ok(hr == S_OK, "got 0x%08x\n", hr);
value = 1;
hr = ITextRange_GetEnd(range2, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 0, "got %d\n", value);
str = SysAllocString(textW);
hr = ITextRange_SetText(range, str);
ok(hr == S_OK, "got 0x%08x\n", hr);
value = 1;
hr = ITextRange_GetStart(range, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 0, "got %d\n", value);
value = 0;
hr = ITextRange_GetEnd(range, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 9, "got %d\n", value);
value = 1;
hr = ITextRange_GetStart(range2, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 0, "got %d\n", value);
value = 0;
hr = ITextRange_GetEnd(range2, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 0, "got %d\n", value);
str = SysAllocStringLen(NULL, 0);
hr = ITextRange_SetText(range, str);
ok(hr == S_OK, "got 0x%08x\n", hr);
value = 1;
hr = ITextRange_GetEnd(range, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 0, "got %d\n", value);
SysFreeString(str);
ITextRange_Release(range2);
release_interfaces(&hwnd, &reOle, &doc, NULL);
hr = ITextRange_SetText(range, NULL);
ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
str = SysAllocStringLen(NULL, 0);
hr = ITextRange_SetText(range, str);
ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
SysFreeString(str);
ITextRange_Release(range);
}
START_TEST(richole)
{
/* Must explicitly LoadLibrary(). The test has no references to functions in
@ -2427,4 +2513,5 @@ START_TEST(richole)
test_dispatch();
test_ITextFont();
test_Delete();
test_SetText();
}