diff options
author | nyamatongwe <unknown> | 2005-05-07 10:50:38 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2005-05-07 10:50:38 +0000 |
commit | 7825cc04da3dad02b57c33fd60c04a45bd148135 (patch) | |
tree | 743366405d3ea3ae36bfee3d36ac355d9d2fda6b | |
parent | 17b4822f0b8879af3cace8fdcf81be235ff6ce8f (diff) | |
download | scintilla-mirror-7825cc04da3dad02b57c33fd60c04a45bd148135.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-- | src/Editor.cxx | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/src/Editor.cxx b/src/Editor.cxx index 6fa7a2ad4..b266ef2a5 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -29,6 +29,37 @@ #include "Document.h" #include "Editor.h" +/* + return whether this modification represents an operation that + may reasonably be deferred (not done now OR [possibly] at all) +*/ +static bool CanDeferToLastStep(const DocModification& mh) { + if (mh.modificationType & (SC_MOD_BEFOREINSERT|SC_MOD_BEFOREDELETE)) + return true; // CAN skip + if (!(mh.modificationType & (SC_PERFORMED_UNDO|SC_PERFORMED_REDO))) + return false; // MUST do + if (mh.modificationType & SC_MULTISTEPUNDOREDO) + return true; // CAN skip + return false; // PRESUMABLY must do +} + +static bool CanEliminate(const DocModification& mh) { + return + (mh.modificationType & (SC_MOD_BEFOREINSERT|SC_MOD_BEFOREDELETE)) != 0; +} + +/* + return whether this modification represents the FINAL step + in a [possibly lengthy] multi-step Undo/Redo sequence +*/ +static bool IsLastStep(const DocModification& mh) { + return + (mh.modificationType & (SC_PERFORMED_UNDO|SC_PERFORMED_REDO)) != 0 + && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0 + && (mh.modificationType & SC_LASTSTEPINUNDOREDO) != 0 + && (mh.modificationType & SC_MULTILINEUNDOREDO) != 0; +} + Caret::Caret() : active(false), on(false), period(500) {} @@ -3385,7 +3416,8 @@ void Editor::Undo() { if (pdoc->CanUndo()) { InvalidateCaret(); int newPos = pdoc->Undo(); - SetEmptySelection(newPos); + if (newPos >= 0) + SetEmptySelection(newPos); EnsureCaretVisible(); } } @@ -3393,7 +3425,8 @@ void Editor::Undo() { void Editor::Redo() { if (pdoc->CanRedo()) { int newPos = pdoc->Redo(); - SetEmptySelection(newPos); + if (newPos >= 0) + SetEmptySelection(newPos); EnsureCaretVisible(); } } @@ -3578,8 +3611,7 @@ void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) { } void Editor::CheckModificationForWrap(DocModification mh) { - if ((mh.modificationType & SC_MOD_INSERTTEXT) || - (mh.modificationType & SC_MOD_DELETETEXT)) { + if (mh.modificationType & (SC_MOD_INSERTTEXT|SC_MOD_DELETETEXT)) { llc.Invalidate(LineLayout::llCheckTextAndStyle); if (wrapState != eWrapNone) { int lineDoc = pdoc->LineFromPosition(mh.position); @@ -3673,7 +3705,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { CheckModificationForWrap(mh); if (mh.linesAdded != 0) { // Avoid scrolling of display if change before current display - if (mh.position < posTopLine) { + if (mh.position < posTopLine && !CanDeferToLastStep(mh)) { int newTop = Platform::Clamp(topLine + mh.linesAdded, 0, MaxScrollPos()); if (newTop != topLine) { SetTopLine(newTop); @@ -3684,19 +3716,19 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { //Platform::DebugPrintf("** %x Doc Changed\n", this); // TODO: could invalidate from mh.startModification to end of screen //InvalidateRange(mh.position, mh.position + mh.length); - if (paintState == notPainting) { + if (paintState == notPainting && !CanDeferToLastStep(mh)) { Redraw(); } } else { //Platform::DebugPrintf("** %x Line Changed %d .. %d\n", this, // mh.position, mh.position + mh.length); - if (paintState == notPainting) { + if (paintState == notPainting && mh.length && !CanEliminate(mh)) { InvalidateRange(mh.position, mh.position + mh.length); } } } - if (mh.linesAdded != 0) { + if (mh.linesAdded != 0 && !CanDeferToLastStep(mh)) { SetScrollBars(); } @@ -3706,6 +3738,12 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { } } + // NOW pay the piper WRT "deferred" visual updates + if (IsLastStep(mh)) { + SetScrollBars(); + Redraw(); + } + // If client wants to see this modification if (mh.modificationType & modEventMask) { if ((mh.modificationType & SC_MOD_CHANGESTYLE) == 0) { @@ -5461,8 +5499,8 @@ void Editor::SetDocPointer(Document *document) { NeedWrapping(); pdoc->AddWatcher(this, 0); - Redraw(); SetScrollBars(); + Redraw(); } /** @@ -5691,7 +5729,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_CANUNDO: - return pdoc->CanUndo() ? 1 : 0; + return (pdoc->CanUndo() && !pdoc->IsReadOnly()) ? 1 : 0; case SCI_EMPTYUNDOBUFFER: pdoc->DeleteUndoHistory(); @@ -6120,7 +6158,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } case SCI_CANREDO: - return pdoc->CanRedo() ? 1 : 0; + return (pdoc->CanRedo() && !pdoc->IsReadOnly()) ? 1 : 0; case SCI_MARKERLINEFROMHANDLE: return pdoc->LineFromHandle(wParam); |