riched20: Implement SetText for regular range.
This commit is contained in:
parent
aa37c179ad
commit
d27234617c
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue