aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornyamatongwe <unknown>2005-05-07 10:50:38 +0000
committernyamatongwe <unknown>2005-05-07 10:50:38 +0000
commit7825cc04da3dad02b57c33fd60c04a45bd148135 (patch)
tree743366405d3ea3ae36bfee3d36ac355d9d2fda6b
parent17b4822f0b8879af3cace8fdcf81be235ff6ce8f (diff)
downloadscintilla-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.cxx60
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);