diff options
author | nyamatongwe <unknown> | 2005-05-07 10:50:38 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2005-05-07 10:50:38 +0000 |
commit | a5947254aab31b2e51f37144206133a8b0e4ac6e (patch) | |
tree | 4bf911b047a0c992d2dfb9e74b63c66ebe0e1e4f | |
parent | 4d4ebd95f2f25e4c814dcd441a98d388e659455a (diff) | |
download | scintilla-mirror-a5947254aab31b2e51f37144206133a8b0e4ac6e.tar.gz |
Patch from Robert that avoids slow performance for multiple step undo
or redo by only modifying the scroll bars at the end.
When document is read only, undo and redo send a SCN_MODIFYATTEMPTRO
notification.
-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; |