diff options
-rw-r--r-- | include/Scintilla.h | 4 | ||||
-rw-r--r-- | include/Scintilla.iface | 4 | ||||
-rw-r--r-- | src/CellBuffer.cxx | 4 | ||||
-rw-r--r-- | src/Document.cxx | 176 |
4 files changed, 108 insertions, 80 deletions
diff --git a/include/Scintilla.h b/include/Scintilla.h index 22b47d65f..5a5a3f0fc 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -618,11 +618,13 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_PERFORMED_USER 0x10 #define SC_PERFORMED_UNDO 0x20 #define SC_PERFORMED_REDO 0x40 +#define SC_MULTISTEPUNDOREDO 0x80 #define SC_LASTSTEPINUNDOREDO 0x100 #define SC_MOD_CHANGEMARKER 0x200 #define SC_MOD_BEFOREINSERT 0x400 #define SC_MOD_BEFOREDELETE 0x800 -#define SC_MODEVENTMASKALL 0xF7F +#define SC_MULTILINEUNDOREDO 0x1000 +#define SC_MODEVENTMASKALL 0x1FFF #define SCEN_CHANGE 768 #define SCEN_SETFOCUS 512 #define SCEN_KILLFOCUS 256 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 5706177c9..1a980486a 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -1669,11 +1669,13 @@ val SC_MOD_CHANGEFOLD=0x8 val SC_PERFORMED_USER=0x10 val SC_PERFORMED_UNDO=0x20 val SC_PERFORMED_REDO=0x40 +val SC_MULTISTEPUNDOREDO=0x80 val SC_LASTSTEPINUNDOREDO=0x100 val SC_MOD_CHANGEMARKER=0x200 val SC_MOD_BEFOREINSERT=0x400 val SC_MOD_BEFOREDELETE=0x800 -val SC_MODEVENTMASKALL=0xF7F +val SC_MULTILINEUNDOREDO=0x1000 +val SC_MODEVENTMASKALL=0x1FFF # For compatibility, these go through the COMMAND notification rather than NOTIFY # and should have had exactly the same values as the EN_* constants. diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx index 772f48e6e..2bb4f5a6c 100644 --- a/src/CellBuffer.cxx +++ b/src/CellBuffer.cxx @@ -1024,7 +1024,7 @@ void CellBuffer::DeleteUndoHistory() { } bool CellBuffer::CanUndo() { - return (!readOnly) && (uh.CanUndo()); + return uh.CanUndo(); } int CellBuffer::StartUndo() { @@ -1052,7 +1052,7 @@ void CellBuffer::PerformUndoStep() { } bool CellBuffer::CanRedo() { - return (!readOnly) && (uh.CanRedo()); + return uh.CanRedo(); } int CellBuffer::StartRedo() { diff --git a/src/Document.cxx b/src/Document.cxx index 0def97a8f..51299b37c 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -336,6 +336,14 @@ void Document::ModifiedAt(int pos) { endStyled = pos; } +void Document::CheckReadOnly() { + if (cb.IsReadOnly() && enteredReadOnlyCount == 0) { + enteredReadOnlyCount++; + NotifyModifyAttempt(); + enteredReadOnlyCount--; + } +} + // Document only modified by gateways DeleteChars, InsertStyledString, Undo, Redo, and SetStyleAt. // SetStyleAt does not change the persistent state of a document @@ -345,11 +353,7 @@ bool Document::DeleteChars(int pos, int len) { return false; if ((pos + len) > Length()) return false; - if (cb.IsReadOnly() && enteredReadOnlyCount == 0) { - enteredReadOnlyCount++; - NotifyModifyAttempt(); - enteredReadOnlyCount--; - } + CheckReadOnly(); if (enteredCount != 0) { return false; } else { @@ -384,11 +388,7 @@ bool Document::DeleteChars(int pos, int len) { * Insert a styled string (char/style pairs) with a length. */ bool Document::InsertStyledString(int position, char *s, int insertLength) { - if (cb.IsReadOnly() && enteredReadOnlyCount == 0) { - enteredReadOnlyCount++; - NotifyModifyAttempt(); - enteredReadOnlyCount--; - } + CheckReadOnly(); if (enteredCount != 0) { return false; } else { @@ -417,86 +417,110 @@ bool Document::InsertStyledString(int position, char *s, int insertLength) { } int Document::Undo() { - int newPos = 0; + int newPos = -1; + CheckReadOnly(); if (enteredCount == 0) { enteredCount++; - bool startSavePoint = cb.IsSavePoint(); - int steps = cb.StartUndo(); - //Platform::DebugPrintf("Steps=%d\n", steps); - for (int step = 0; step < steps; step++) { - int prevLinesTotal = LinesTotal(); - const Action &action = cb.GetUndoStep(); - if (action.at == removeAction) { - NotifyModified(DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action)); - } else { - NotifyModified(DocModification( - SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action)); - } - cb.PerformUndoStep(); - int cellPosition = action.position / 2; - ModifiedAt(cellPosition); - newPos = cellPosition; - - int modFlags = SC_PERFORMED_UNDO; - // With undo, an insertion action becomes a deletion notification - if (action.at == removeAction) { - newPos += action.lenData; - modFlags |= SC_MOD_INSERTTEXT; - } else { - modFlags |= SC_MOD_DELETETEXT; + if (!cb.IsReadOnly()) { + bool startSavePoint = cb.IsSavePoint(); + bool multiLine = false; + int steps = cb.StartUndo(); + //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 { + NotifyModified(DocModification( + SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action)); + } + cb.PerformUndoStep(); + int cellPosition = action.position / 2; + ModifiedAt(cellPosition); + newPos = cellPosition; + + int modFlags = SC_PERFORMED_UNDO; + // With undo, an insertion action becomes a deletion notification + if (action.at == removeAction) { + newPos += action.lenData; + modFlags |= SC_MOD_INSERTTEXT; + } else { + 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, cellPosition, action.lenData, + linesAdded, action.data)); } - if (step == steps - 1) - modFlags |= SC_LASTSTEPINUNDOREDO; - NotifyModified(DocModification(modFlags, cellPosition, action.lenData, - LinesTotal() - prevLinesTotal, action.data)); - } - bool endSavePoint = cb.IsSavePoint(); - if (startSavePoint != endSavePoint) - NotifySavePoint(endSavePoint); + bool endSavePoint = cb.IsSavePoint(); + if (startSavePoint != endSavePoint) + NotifySavePoint(endSavePoint); + } enteredCount--; } return newPos; } int Document::Redo() { - int newPos = 0; + int newPos = -1; + CheckReadOnly(); if (enteredCount == 0) { enteredCount++; - bool startSavePoint = cb.IsSavePoint(); - int steps = cb.StartRedo(); - for (int step = 0; step < steps; step++) { - int prevLinesTotal = LinesTotal(); - const Action &action = cb.GetRedoStep(); - if (action.at == insertAction) { - NotifyModified(DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action)); - } else { - NotifyModified(DocModification( - SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action)); - } - cb.PerformRedoStep(); - ModifiedAt(action.position / 2); - newPos = action.position / 2; - - int modFlags = SC_PERFORMED_REDO; - if (action.at == insertAction) { - newPos += action.lenData; - modFlags |= SC_MOD_INSERTTEXT; - } else { - modFlags |= SC_MOD_DELETETEXT; + if (!cb.IsReadOnly()) { + bool startSavePoint = cb.IsSavePoint(); + bool multiLine = false; + int steps = cb.StartRedo(); + for (int step = 0; step < steps; step++) { + const int prevLinesTotal = LinesTotal(); + const Action &action = cb.GetRedoStep(); + if (action.at == insertAction) { + NotifyModified(DocModification( + SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action)); + } else { + NotifyModified(DocModification( + SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action)); + } + cb.PerformRedoStep(); + ModifiedAt(action.position / 2); + newPos = action.position / 2; + + int modFlags = SC_PERFORMED_REDO; + if (action.at == insertAction) { + newPos += action.lenData; + modFlags |= SC_MOD_INSERTTEXT; + } else { + 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 / 2, action.lenData, + linesAdded, action.data)); } - if (step == steps - 1) - modFlags |= SC_LASTSTEPINUNDOREDO; - NotifyModified( - DocModification(modFlags, action.position / 2, action.lenData, - LinesTotal() - prevLinesTotal, action.data)); - } - bool endSavePoint = cb.IsSavePoint(); - if (startSavePoint != endSavePoint) - NotifySavePoint(endSavePoint); + bool endSavePoint = cb.IsSavePoint(); + if (startSavePoint != endSavePoint) + NotifySavePoint(endSavePoint); + } enteredCount--; } return newPos; |