diff options
author | Neil <nyamatongwe@gmail.com> | 2014-07-18 23:37:23 +1000 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2014-07-18 23:37:23 +1000 |
commit | 286895b1a01a6fd57b9fd5044efad711e9c2216b (patch) | |
tree | f8fbc009263db18ff89876e4600ac5910c3e227d /src/Document.cxx | |
parent | 2fc9c2d3742b5b09a6e1ec40d32e4d93f83df5ca (diff) | |
download | scintilla-mirror-286895b1a01a6fd57b9fd5044efad711e9c2216b.tar.gz |
Added the tentative undo feature. This is useful for IMEs that want to display
and manipulate a character being composed, but may then commit or remove it
leaving no history in undo of the intermediate forms.
Diffstat (limited to 'src/Document.cxx')
-rw-r--r-- | src/Document.cxx | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/Document.cxx b/src/Document.cxx index 32d5f1896..4c1901679 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -209,6 +209,65 @@ void Document::SetSavePoint() { NotifySavePoint(true); } +void Document::TentativeUndo() { + CheckReadOnly(); + if (enteredModification == 0) { + enteredModification++; + if (!cb.IsReadOnly()) { + bool startSavePoint = cb.IsSavePoint(); + bool multiLine = false; + int steps = cb.TentativeSteps(); + //Platform::DebugPrintf("Steps=%d\n", steps); + for (int step = 0; step < steps; step++) { + const int prevLinesTotal = LinesTotal(); + const Action &action = cb.GetUndoStep(); + if (action.at == removeAction) { + NotifyModified(DocModification( + SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action)); + } else if (action.at == containerAction) { + DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO); + dm.token = action.position; + NotifyModified(dm); + } else { + NotifyModified(DocModification( + SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action)); + } + cb.PerformUndoStep(); + if (action.at != containerAction) { + ModifiedAt(action.position); + } + + int modFlags = SC_PERFORMED_UNDO; + // With undo, an insertion action becomes a deletion notification + if (action.at == removeAction) { + modFlags |= SC_MOD_INSERTTEXT; + } else if (action.at == insertAction) { + modFlags |= SC_MOD_DELETETEXT; + } + if (steps > 1) + modFlags |= SC_MULTISTEPUNDOREDO; + const int linesAdded = LinesTotal() - prevLinesTotal; + if (linesAdded != 0) + multiLine = true; + if (step == steps - 1) { + modFlags |= SC_LASTSTEPINUNDOREDO; + if (multiLine) + modFlags |= SC_MULTILINEUNDOREDO; + } + NotifyModified(DocModification(modFlags, action.position, action.lenData, + linesAdded, action.data)); + } + + bool endSavePoint = cb.IsSavePoint(); + if (startSavePoint != endSavePoint) + NotifySavePoint(endSavePoint); + + cb.TentativeCommit(); + } + enteredModification--; + } +} + int Document::GetMark(int line) { return static_cast<LineMarkers *>(perLineData[ldMarkers])->MarkValue(line); } |