riched20: Create undos in StreamIn at the right times. Adds tests
for when StreamIn should be undoable.
Matt Finnicum
mattfinn at gmail.com
Thu Jan 25 00:11:07 CST 2007
This patch modifies ME_StreamIn so that it creates undos when called
with SFF_SELECTION and doesn't otherwise. Adds some additional tests
that show this working well. Also, this cleans up usual StreamIn
process in that there is no creating-and-later-deleting of pointless
undos. Fixes bug 7148.
---
dlls/riched20/editor.c | 28 +++++++----
dlls/riched20/tests/editor.c | 101 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 119 insertions(+), 10 deletions(-)
-------------- next part --------------
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 9b1904d..e3e4ba3 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -597,7 +597,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
{
RTF_Info parser;
ME_Style *style;
- int from, to, to2;
+ int from, to, to2, nUndoMode;
int nEventMask = editor->nEventMask;
ME_InStream inStream;
@@ -619,7 +619,15 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
ME_ClearTempStyle(editor);
/* FIXME restore default paragraph formatting ! */
}
-
+
+
+ /* Back up undo mode to a local variable */
+ nUndoMode = editor->nUndoMode;
+
+ /* Only create an undo if SFF_SELECTION is set */
+ if (!(format & SFF_SELECTION))
+ editor->nUndoMode = umIgnore;
+
inStream.editstream = stream;
inStream.editstream->dwError = 0;
inStream.dwSize = 0;
@@ -671,15 +679,15 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
SendMessageA(editor->hWnd, EM_SETSEL, 0, 0);
}
- if (format & SFF_SELECTION)
- {
- /* even if we didn't add an undo, we need to commit the ones added earlier */
- ME_CommitUndo(editor);
- }
- else
- {
+ /* Restore saved undo mode */
+ editor->nUndoMode = nUndoMode;
+
+ /* even if we didn't add an undo, we need to commit anything on the stack */
+ ME_CommitUndo(editor);
+
+ /* If SFF_SELECTION isn't set, delete any undos from before we started too */
+ if (!(format & SFF_SELECTION))
ME_EmptyUndoStack(editor);
- }
ME_ReleaseStyle(style);
editor->nEventMask = nEventMask;
diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c
index f86ca5a..6a7cb62 100644
--- a/dlls/riched20/tests/editor.c
+++ b/dlls/riched20/tests/editor.c
@@ -1462,6 +1462,106 @@ static void test_WM_PASTE(void)
DestroyWindow(hwndRichEdit);
}
+static int nCallbackCount = 0;
+
+static DWORD CALLBACK EditStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff,
+ LONG cb, LONG* pcb)
+{
+ const char text[] = {'t','e','s','t'};
+
+ if (sizeof(text) <= cb)
+ {
+ if ((int)dwCookie != nCallbackCount)
+ {
+ *pcb = 0;
+ return 0;
+ }
+
+ memcpy (pbBuff, text, sizeof(text));
+ *pcb = sizeof(text);
+
+ nCallbackCount++;
+
+ return 0;
+ }
+ else
+ return 1; /* indicates callback failed */
+}
+
+static void test_EM_StreamIn_Undo(void)
+{
+ /* The purpose of this test is to determine when a EM_StreamIn should be
+ * undoable. This is important because WM_PASTE currently uses StreamIn and
+ * pasting should always be undoable but streaming isn't always.
+ *
+ * cases to test:
+ * StreamIn plain text without SFF_SELECTION.
+ * StreamIn plain text with SFF_SELECTION set but a zero-length selection
+ * StreamIn plain text with SFF_SELECTION and a valid, normal selection
+ * StreamIn plain text with SFF_SELECTION and a backwards-selection (from>to)
+ * Feel free to add tests for other text modes or StreamIn things.
+ */
+
+
+ HWND hwndRichEdit = new_richedit(NULL);
+ LRESULT result;
+ EDITSTREAM es;
+ char buffer[1024] = {0};
+ const char randomtext[] = "Some text";
+
+ es.pfnCallback = (EDITSTREAMCALLBACK) EditStreamCallback;
+
+ /* StreamIn, no SFF_SELECTION */
+ es.dwCookie = nCallbackCount;
+ SendMessage(hwndRichEdit,EM_EMPTYUNDOBUFFER, 0,0);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) randomtext);
+ SendMessage(hwndRichEdit, EM_SETSEL,0,0);
+ SendMessage(hwndRichEdit, EM_STREAMIN, (WPARAM)SF_TEXT, (LPARAM)&es);
+ SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
+ result = strcmp (buffer,"test");
+ ok (result == 0,
+ "EM_STREAMIN: Test 1 set wrong text: Result: %s\n",buffer);
+
+ result = SendMessage(hwndRichEdit, EM_CANUNDO, 0, 0);
+ ok (result == FALSE,
+ "EM_STREAMIN without SFF_SELECTION wrongly allows undo\n");
+
+ /* StreamIn, SFF_SELECTION, but nothing selected */
+ es.dwCookie = nCallbackCount;
+ SendMessage(hwndRichEdit,EM_EMPTYUNDOBUFFER, 0,0);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) randomtext);
+ SendMessage(hwndRichEdit, EM_SETSEL,0,0);
+ SendMessage(hwndRichEdit, EM_STREAMIN,
+ (WPARAM)(SF_TEXT|SFF_SELECTION), (LPARAM)&es);
+ SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
+ result = strcmp (buffer,"testSome text");
+ ok (result == 0,
+ "EM_STREAMIN: Test 2 set wrong text: Result: %s\n",buffer);
+
+ result = SendMessage(hwndRichEdit, EM_CANUNDO, 0, 0);
+ ok (result == TRUE,
+ "EM_STREAMIN with SFF_SELECTION but no selection set "
+ "should create an undo\n");
+
+ /* StreamIn, SFF_SELECTION, with a selection */
+ es.dwCookie = nCallbackCount;
+ SendMessage(hwndRichEdit,EM_EMPTYUNDOBUFFER, 0,0);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) randomtext);
+ SendMessage(hwndRichEdit, EM_SETSEL,4,5);
+ SendMessage(hwndRichEdit, EM_STREAMIN,
+ (WPARAM)(SF_TEXT|SFF_SELECTION), (LPARAM)&es);
+ SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
+ result = strcmp (buffer,"Sometesttext");
+ ok (result == 0,
+ "EM_STREAMIN: Test 2 set wrong text: Result: %s\n",buffer);
+
+ result = SendMessage(hwndRichEdit, EM_CANUNDO, 0, 0);
+ ok (result == TRUE,
+ "EM_STREAMIN with SFF_SELECTION and selection set "
+ "should create an undo\n");
+
+}
+
START_TEST( editor )
{
MSG msg;
@@ -1490,6 +1590,7 @@ START_TEST( editor )
test_EM_GETMODIFY();
test_EM_EXSETSEL();
test_WM_PASTE();
+ test_EM_StreamIn_Undo();
/* Set the environment variable WINETEST_RICHED20 to keep windows
* responsive and open for 30 seconds. This is useful for debugging.
--
1.4.4.4
More information about the wine-patches
mailing list