Jinoh Kang : riched20: Implement ITextDocument::Undo and ITextDocument::Redo.
Alexandre Julliard
julliard at winehq.org
Thu Jul 14 16:59:25 CDT 2022
Module: wine
Branch: master
Commit: ded8227774570a1ea320dc34f2de0033f85b3ce7
URL: https://gitlab.winehq.org/wine/wine/-/commit/ded8227774570a1ea320dc34f2de0033f85b3ce7
Author: Jinoh Kang <jinoh.kang.kr at gmail.com>
Date: Tue Jun 28 00:30:06 2022 +0900
riched20: Implement ITextDocument::Undo and ITextDocument::Redo.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53289
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
dlls/riched20/editor.c | 1 +
dlls/riched20/editor.h | 2 ++
dlls/riched20/richole.c | 48 +++++++++++++++++++++++++++++++++++++++----
dlls/riched20/tests/richole.c | 30 +++++----------------------
dlls/riched20/undo.c | 14 +++++++++++++
5 files changed, 66 insertions(+), 29 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index a1e0395f24d..108c37a7f30 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -3299,6 +3299,7 @@ LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam,
}
case EM_SETUNDOLIMIT:
{
+ editor_enable_undo(editor);
if ((int)wParam < 0)
editor->nUndoLimit = STACK_SIZE_DEFAULT;
else
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index d10ff225335..072d0f62782 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -393,6 +393,8 @@ void ME_CommitCoalescingUndo(ME_TextEditor *editor) DECLSPEC_HIDDEN;
BOOL ME_Undo(ME_TextEditor *editor) DECLSPEC_HIDDEN;
BOOL ME_Redo(ME_TextEditor *editor) DECLSPEC_HIDDEN;
void ME_EmptyUndoStack(ME_TextEditor *editor) DECLSPEC_HIDDEN;
+void editor_disable_undo(ME_TextEditor *editor);
+void editor_enable_undo(ME_TextEditor *editor);
static inline BOOL editor_undo_ignored(ME_TextEditor *editor)
{
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c
index afecd34dc2a..8190a4e2753 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -4245,15 +4245,55 @@ static HRESULT WINAPI ITextDocument2Old_fnEndEditCollection(ITextDocument2Old *i
static HRESULT WINAPI ITextDocument2Old_fnUndo(ITextDocument2Old *iface, LONG Count, LONG *prop)
{
struct text_services *services = impl_from_ITextDocument2Old(iface);
- FIXME("stub %p\n", services);
- return E_NOTIMPL;
+ LONG actual_undo_count;
+
+ if (prop) *prop = 0;
+
+ switch (Count)
+ {
+ case tomFalse:
+ editor_disable_undo(services->editor);
+ return S_OK;
+ default:
+ if (Count > 0) break;
+ /* fallthrough */
+ case tomTrue:
+ editor_enable_undo(services->editor);
+ return S_FALSE;
+ case tomSuspend:
+ if (services->editor->undo_ctl_state == undoActive)
+ {
+ services->editor->undo_ctl_state = undoSuspended;
+ }
+ return S_FALSE;
+ case tomResume:
+ services->editor->undo_ctl_state = undoActive;
+ return S_FALSE;
+ }
+
+ for (actual_undo_count = 0; actual_undo_count < Count; actual_undo_count++)
+ {
+ if (!ME_Undo(services->editor)) break;
+ }
+
+ if (prop) *prop = actual_undo_count;
+ return actual_undo_count == Count ? S_OK : S_FALSE;
}
static HRESULT WINAPI ITextDocument2Old_fnRedo(ITextDocument2Old *iface, LONG Count, LONG *prop)
{
struct text_services *services = impl_from_ITextDocument2Old(iface);
- FIXME("stub %p\n", services);
- return E_NOTIMPL;
+ LONG actual_redo_count;
+
+ if (prop) *prop = 0;
+
+ for (actual_redo_count = 0; actual_redo_count < Count; actual_redo_count++)
+ {
+ if (!ME_Redo(services->editor)) break;
+ }
+
+ if (prop) *prop = actual_redo_count;
+ return actual_redo_count == Count ? S_OK : S_FALSE;
}
static HRESULT CreateITextRange(struct text_services *services, LONG start, LONG end, ITextRange** ppRange)
diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c
index a01f4e21db8..1ebc12a27ab 100644
--- a/dlls/riched20/tests/richole.c
+++ b/dlls/riched20/tests/richole.c
@@ -4940,8 +4940,8 @@ static void test_clipboard(void)
ok(hr == S_OK, "Cut failed: 0x%08lx\n", hr);
CLIPBOARD_RANGE_CONTAINS(range, 0, 4, "b\r\n c");
hr = ITextDocument_Undo(doc, 1, NULL);
- todo_wine ok(hr == S_OK, "Undo failed: 0x%08lx\n", hr);
- TODO_CLIPBOARD_RANGE_CONTAINS(range, 0, 5, "ab\r\n c");
+ ok(hr == S_OK, "Undo failed: 0x%08lx\n", hr);
+ CLIPBOARD_RANGE_CONTAINS(range, 0, 5, "ab\r\n c");
/* Cannot cut when read-only */
SendMessageA(hwnd, EM_SETREADONLY, TRUE, 0);
@@ -4986,26 +4986,23 @@ static void subtest_undo(const char *dummy_text)
if (i != tomFalse && i != tomTrue)
{
hr = ITextDocument_Undo(doc, i, NULL);
- todo_wine
+ todo_wine_if(i >= 1)
ok(hr == (i >= 1 ? S_OK : S_FALSE), "(%ld at 0) Undo: %#lx\n", i, hr);
count = 0xcccccccc;
hr = ITextDocument_Undo(doc, i, &count);
- todo_wine
+ todo_wine_if(i >= 1)
ok(hr == (i >= 1 ? S_OK : S_FALSE), "(%ld at 0) Undo: %#lx\n", i, hr);
- todo_wine
+ todo_wine_if(i >= 1)
ok(count == (i >= 1 ? i : 0), "(%ld at 0) Expected %ld, got %ld\n", i, i >= 0 ? i : 0, count);
}
hr = ITextDocument_Redo(doc, i, NULL);
- todo_wine
ok(hr == (i == 0 ? S_OK : S_FALSE), "(%ld at 0) Redo: %#lx\n", i, hr);
count = 0xcccccccc;
hr = ITextDocument_Redo(doc, i, &count);
- todo_wine
ok(hr == (i == 0 ? S_OK : S_FALSE), "(%ld at 0) Redo: %#lx\n", i, hr);
- todo_wine
ok(count == 0, "(%ld at 0) got %ld\n", i, count);
}
@@ -5015,7 +5012,6 @@ static void subtest_undo(const char *dummy_text)
if (dummy_text)
{
hr = ITextDocument_Undo(doc, tomSuspend, NULL);
- todo_wine
ok(hr == S_FALSE, "(@%ld) Undo: %#lx\n", stack_pos, hr);
if (SUCCEEDED(hr))
{
@@ -5024,7 +5020,6 @@ static void subtest_undo(const char *dummy_text)
SendMessageA(hwnd, EM_SETSEL, 0, strlen(dummy_text));
SendMessageA(hwnd, EM_REPLACESEL, TRUE, (LPARAM)"");
hr = ITextDocument_Undo(doc, tomResume, NULL);
- todo_wine
ok(hr == S_FALSE, "(@%ld) Undo: %#lx\n", stack_pos, hr);
}
}
@@ -5038,7 +5033,6 @@ static void subtest_undo(const char *dummy_text)
memset(buffer, 0, sizeof(buffer));
SendMessageA(hwnd, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
- todo_wine_if(stack_pos != ARRAY_SIZE(text_seq) - 1)
ok(strcmp(buffer, text_seq[stack_pos]) == 0, "Expected %s, got %s\n",
wine_dbgstr_a(text_seq[stack_pos]), wine_dbgstr_a(buffer));
@@ -5049,18 +5043,14 @@ static void subtest_undo(const char *dummy_text)
if (seq[i] < 0)
{
hr = ITextDocument_Undo(doc, -seq[i], &count);
- todo_wine
ok(hr == S_OK, "(%ld@%ld) Undo: %#lx\n", i, stack_pos, hr);
- todo_wine
ok(count == expect_count, "(%ld@%ld) Expected %ld, got %ld\n", i, stack_pos, expect_count, count);
stack_pos -= count;
}
else
{
hr = ITextDocument_Redo(doc, seq[i], &count);
- todo_wine
ok(hr == (expect_count ? S_OK : S_FALSE), "(%ld@%ld) Redo: %#lx\n", i, stack_pos, hr);
- todo_wine
ok(count == expect_count, "(%ld@%ld) Expected %ld, got %ld\n", i, stack_pos, expect_count, count);
stack_pos += count;
}
@@ -5145,7 +5135,6 @@ static HRESULT perform_editor_undo_state_action(struct undo_test *inst, enum edi
else
{
hr = ITextDocument_Undo(inst->doc, tomTrue, count);
- todo_wine
ok(hr == S_FALSE, "Undo: %#lx\n", hr);
}
if (SUCCEEDED(hr))
@@ -5159,7 +5148,6 @@ static HRESULT perform_editor_undo_state_action(struct undo_test *inst, enum edi
break;
case undoActionDisable:
hr = ITextDocument_Undo(inst->doc, tomFalse, count);
- todo_wine
ok(hr == S_OK, "Undo: %#lx\n", hr);
if (SUCCEEDED(hr))
{
@@ -5170,7 +5158,6 @@ static HRESULT perform_editor_undo_state_action(struct undo_test *inst, enum edi
break;
case undoActionSuspend:
hr = ITextDocument_Undo(inst->doc, tomSuspend, count);
- todo_wine
ok(hr == S_FALSE, "Undo: %#lx\n", hr);
if (SUCCEEDED(hr) && inst->undo_ctl_state == undoStateActive)
{
@@ -5179,7 +5166,6 @@ static HRESULT perform_editor_undo_state_action(struct undo_test *inst, enum edi
break;
case undoActionResume:
hr = ITextDocument_Undo(inst->doc, tomResume, count);
- todo_wine
ok(hr == S_FALSE, "Undo: %#lx\n", hr);
if (SUCCEEDED(hr))
{
@@ -5193,7 +5179,6 @@ static HRESULT perform_editor_undo_state_action(struct undo_test *inst, enum edi
if (count)
{
- todo_wine
ok(*count == 0, "Got %ld\n", *count);
}
return hr;
@@ -5221,7 +5206,6 @@ static HRESULT set_editor_undo_state(struct undo_test *inst, enum editorUndoStat
break;
}
ok(inst->undo_ctl_state == state, "expected state %d, got %d\n", state, inst->undo_ctl_state);
- todo_wine
ok(SUCCEEDED(hr), "cannot set state to %d: %#lx\n", undoStateActive, hr);
return hr;
}
@@ -5243,9 +5227,7 @@ static BOOL perform_undo_(struct undo_test *inst, BOOL can_undo, int line)
{
count = 0xcccccccc;
hr = ITextDocument_Undo(inst->doc, 1, &count);
- todo_wine
ok_(__FILE__, line)(SUCCEEDED(hr), "got hr %#lx\n", hr);
- todo_wine
ok_(__FILE__, line)(count == (hr == S_OK), "expected count %d, got %ld\n", hr == S_OK, count);
result = hr == S_OK && count > 0;
}
@@ -5279,9 +5261,7 @@ static BOOL perform_redo_(struct undo_test *inst, BOOL can_redo, int line)
{
count = 0xcccccccc;
hr = ITextDocument_Redo(inst->doc, 1, &count);
- todo_wine
ok_(__FILE__, line)(SUCCEEDED(hr), "got hr %#lx\n", hr);
- todo_wine
ok_(__FILE__, line)(count == (hr == S_OK), "expected count %d, got %ld\n", hr == S_OK, count);
result = hr == S_OK && count > 0;
}
diff --git a/dlls/riched20/undo.c b/dlls/riched20/undo.c
index 607f90130d5..6e0c7c896ef 100644
--- a/dlls/riched20/undo.c
+++ b/dlls/riched20/undo.c
@@ -479,3 +479,17 @@ BOOL ME_Redo(ME_TextEditor *editor)
ME_UpdateRepaint(editor, FALSE);
return TRUE;
}
+
+void editor_disable_undo(ME_TextEditor *editor)
+{
+ ME_EmptyUndoStack(editor);
+ editor->undo_ctl_state = undoDisabled;
+}
+
+void editor_enable_undo(ME_TextEditor *editor)
+{
+ if (editor->undo_ctl_state == undoDisabled)
+ {
+ editor->undo_ctl_state = undoActive;
+ }
+}
More information about the wine-cvs
mailing list