diff options
Diffstat (limited to 'src/Editor.cxx')
-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); |