Javaв„ў EE 5 Tutorial, The (3rd Edition)
I wish I had checkpointed the source code before putting in all the experiments for speed. Now I ll have to take them out manually, and I ll also remove those new Insert methods from TextModel. No, wait! That might get me in trouble. My customer test for undo is failing because of the new insertion method, going through the notepad. I do want to get there, but if I m going to clean up code, I need the tests to support me. So first I ll get green again, by reverting to the previous version of the TypeCharacters code in CustomerTest:
private void TypeCharacters(String s) { foreach (char c in s) { model.InsertCharacter(c); // form.XMLKeyDownHandler( // (object) this, // new KeyEventArgs( // (Keys) Enum.Parse(typeof(Keys), c.ToString(), true))); } }
Now my tests run; it s safe to start removing things. I m going to look at each reference to Snapshot() and Restore() and check whether I can remove them. Outside the tests, here s where they are:
In XMLNotepad.cs:
public void XMLKeyDownHandler(object objSender, KeyEventArgs kea) { if (kea.KeyCode != Keys.ControlKey && kea.KeyCode != Keys.Alt && kea.KeyCode != Keys.ShiftKey) { GetText(); model.Snapshot(); } if (kea.KeyCode == Keys.Enter && kea.Modifiers == Keys.None) { CallModel(enterAction); kea.Handled = true; } else if (kea.KeyCode == Keys.Enter && kea.Modifiers == Keys.Shift) { CallModel(shiftEnterAction); kea.Handled = true; } else if (kea.KeyCode == Keys.Y && kea.Modifiers == Keys.Control) { Console.WriteLine("keydown Y"); kea.Handled = true; } }
In TextModel.cs:
public void Enter() { Snapshot(); if (InListItem()) InsertTags(Tags.ListItem); else InsertTags(Tags.Paragraph); } public void InsertTags(InsertAction action) { Snapshot(); int cursorLine = LineContainingCursor(); lines.InsertRange(cursorLine+1, action.TagsToInsert); selectionStart = NewSelectionStart(cursorLine + 1, action.TagsToSkip); } public void InsertCharacter(char c) { Snapshot(); lines[LineContainingCursor()] = FrontOfCursorLine() + c + BackOfCursorLine(); selectionStart++; }
The duplication in the TextModel bugs me. And it makes me think. Maybe that code in the KeyDownHandler is almost right: it is doing a Snapshot on every character. I m not sure whether the GetText() should be done first or second, but that s almost in the right place. What if we just leave that one in and remove all the others. What would break? I ll find out.
The only thing that breaks is the undo test, with this message:
c:\data\csharp\notepad\undo.test *Expected <P>ab</P> *Result
Look again at the test:
*enter *type abc *output <P>abc</P> *end *undo *output <P>ab</P> *end *undo *output <P>a</P> *end *undo *output <P></P> *end *undo *output *end
The failure is happening after the first undo. We expect it to erase just the c, but the result is that it erases everything. What s up with that? Well, at this point, we are still using the InsertCharacter() and not going through the notepad event. Let s change that back to the new way:
private void TypeCharacters(String s) { foreach (char c in s) { form.XMLKeyDownHandler( (object) this, new KeyEventArgs( (Keys) Enum.Parse(typeof(Keys), c.ToString(), true))); } }
This nearly works ”well, it fails differently:
c:\data\csharp\notepad\undo.test *Expected <P>abc</P> *Result <P></P>
Looking at the test, we see that this tells us that the characters abc are not over in the TextModel. I m not sure why not. I expect this code to move the text from the TextBox to the TextModel on every character:
public void XMLKeyDownHandler(object objSender, KeyEventArgs kea) { if (kea.KeyCode != Keys.ControlKey && kea.KeyCode != Keys.Alt && kea.KeyCode != Keys.ShiftKey) { GetText(); model.Snapshot(); } ...
I m not sure the characters are ever getting into the TextBox at all. We ve always been a bit unclear about which of the events the TextBox itself uses. Updating the undo test as follows gives the answer:
*enter *type abc *enter *display *output <P>abc</P>
When we run this test, the output is
display <P></P> <P></P> end
As we suspected, the characters aren t being sent over to the TextBox. Very likely the TextBox uses the KeyPress event rather than the KeyDown. We ll change TypeCharacter to use that event:
private void TypeCharacters(String s) { foreach (char c in s) { form.XMLKeyDownHandler( (object) this, new KeyEventArgs( (Keys) Enum.Parse(typeof(Keys), c.ToString(), true))); form.XMLKeyPressHandler((object) this, new KeyPressEventArgs(c)); } }
This has no effect whatever on the test. The keys still aren t going into the TextModel. I m not sure if the TextBox isn t seeing them or what.
Категории