aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Editor.cxx
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2005-05-07 10:50:38 +0000
committernyamatongwe <devnull@localhost>2005-05-07 10:50:38 +0000
commit701e69afd3448ae516372aefd5981f658563411f (patch)
tree743366405d3ea3ae36bfee3d36ac355d9d2fda6b /src/Editor.cxx
parentdd8c5b4b131afe4ec681c20e3b361ea80728a030 (diff)
downloadscintilla-mirror-701e69afd3448ae516372aefd5981f658563411f.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.
Diffstat (limited to 'src/Editor.cxx')
-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);