aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/ScintillaDoc.html33
-rw-r--r--include/Scintilla.h6
-rw-r--r--include/Scintilla.iface7
-rw-r--r--src/CellBuffer.cxx8
-rw-r--r--src/CellBuffer.h3
-rw-r--r--src/Document.cxx24
-rw-r--r--src/Document.h8
-rw-r--r--src/Editor.cxx5
8 files changed, 82 insertions, 12 deletions
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html
index cf869e1c0..c6f9fe46a 100644
--- a/doc/ScintillaDoc.html
+++ b/doc/ScintillaDoc.html
@@ -899,6 +899,7 @@ struct TextToFind {
<a class="message" href="#SCI_GETUNDOCOLLECTION">SCI_GETUNDOCOLLECTION</a><br />
<a class="message" href="#SCI_BEGINUNDOACTION">SCI_BEGINUNDOACTION</a><br />
<a class="message" href="#SCI_ENDUNDOACTION">SCI_ENDUNDOACTION</a><br />
+ <a class="message" href="#SCI_ADDUNDOACTION">SCI_ADDUNDOACTION(int token)</a><br />
</code>
<p><b id="SCI_UNDO">SCI_UNDO</b><br />
@@ -946,6 +947,24 @@ struct TextToFind {
Alternatively, you can use these to mark a set of operations that you do not want to have
combined with the preceding or following operations if they are undone.</p>
+ <p><b id="SCI_ADDUNDOACTION">SCI_ADDUNDOACTION(int token)</b><br />
+ The container can add its own actions into the undo stack by calling
+ <code>SCI_ADDUNDOACTION</code> and an <code>SCN_MODIFIED</code>
+ notification will be sent to the container with the
+ <a class="message" href="#SC_MOD_CONTAINER"><code>SC_MOD_CONTAINER</code></a>
+ flag when it is time to undo (<code>SC_PERFORMED_UNDO</code>) or
+ redo (<code>SC_PERFORMED_REDO</code>) the action. The token argument supplied is
+ returned in the <code>token</code> field of the notification.</p>
+ <p>For example, if the container wanted to allow undo and redo of a 'toggle bookmark' command then
+ it could call <code>SCI_ADDUNDOACTION(line)</code> each time the command is performed.
+ Then when it receives a notification to undo or redo it toggles a bookmark on the line given by
+ the token field. If there are different types of commands or parameters that need to be stored into the undo
+ stack then the container should maintain a stack of its own for the document and use the current
+ position in that stack as the argument to <code>SCI_ADDUNDOACTION(line)</code>.
+ <code>SCI_ADDUNDOACTION</code> commands are not combined together
+ into a single undo transaction unless grouped with <code>SCI_BEGINUNDOACTION</code>
+ and <code>SCI_ENDUNDOACTION</code>.</p>
+
<h2 id="SelectionAndInformation">Selection and information</h2>
<p>Scintilla maintains a selection that stretches between two points, the anchor and the
@@ -5209,9 +5228,21 @@ href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber);
</tr>
<tr>
+ <td align="left"><code id="SC_MOD_CONTAINER">SC_MOD_CONTAINER</code></td>
+
+ <td align="center">0x40000</td>
+
+ <td>This is set on for actions that the container stored into the undo stack with
+ <a class="message" href="#SCI_ADDUNDOACTION"><code>SCI_ADDUNDOACTION</code></a>.
+ </td>
+
+ <td>token</td>
+ </tr>
+
+ <tr>
<td align="left"><code>SC_MODEVENTMASKALL</code></td>
- <td align="center">0x1fff</td>
+ <td align="center">0x7FFFF</td>
<td>This is a mask for all valid flags. This is the default mask state set by <a
class="message" href="#SCI_SETMODEVENTMASK"><code>SCI_SETMODEVENTMASK</code></a>.</td>
diff --git a/include/Scintilla.h b/include/Scintilla.h
index 6c3509344..4cc67529a 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -119,6 +119,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SC_MARK_PIXMAP 25
#define SC_MARK_FULLRECT 26
#define SC_MARK_LEFTRECT 27
+#define SC_MARK_AVAILABLE 28
#define SC_MARK_CHARACTER 10000
#define SC_MARKNUM_FOLDEREND 25
#define SC_MARKNUM_FOLDEROPENMID 26
@@ -678,6 +679,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_SETEXTRADESCENT 2527
#define SCI_GETEXTRADESCENT 2528
#define SCI_MARKERSYMBOLDEFINED 2529
+#define SCI_ADDUNDOACTION 2560
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
@@ -708,7 +710,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SC_STARTACTION 0x2000
#define SC_MOD_CHANGEINDICATOR 0x4000
#define SC_MOD_CHANGELINESTATE 0x8000
-#define SC_MODEVENTMASKALL 0xFFFF
+#define SC_MOD_CONTAINER 0x40000
+#define SC_MODEVENTMASKALL 0x7FFFF
#define SCEN_CHANGE 768
#define SCEN_SETFOCUS 512
#define SCEN_KILLFOCUS 256
@@ -831,6 +834,7 @@ struct SCNotification {
int listType; /* SCN_USERLISTSELECTION */
int x; /* SCN_DWELLSTART, SCN_DWELLEND */
int y; /* SCN_DWELLSTART, SCN_DWELLEND */
+ int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */
};
#ifdef SCI_NAMESPACE
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index ed31a803e..426a2c886 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -1832,6 +1832,9 @@ get int GetExtraDescent=2528(,)
# Which symbol was defined for markerNumber with MarkerDefine
fun int MarkerSymbolDefined=2529(int markerNumber,)
+# Add a container action to the undo stack
+fun void AddUndoAction=2560(int token,)
+
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
@@ -1897,7 +1900,9 @@ val SC_MULTILINEUNDOREDO=0x1000
val SC_STARTACTION=0x2000
val SC_MOD_CHANGEINDICATOR=0x4000
val SC_MOD_CHANGELINESTATE=0x8000
-val SC_MODEVENTMASKALL=0xFFFF
+
+val SC_MOD_CONTAINER=0x40000
+val SC_MODEVENTMASKALL=0x7FFFF
# 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 0e9ae6950..ccb357a41 100644
--- a/src/CellBuffer.cxx
+++ b/src/CellBuffer.cxx
@@ -424,6 +424,9 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
} else if (!actions[currentAction].mayCoalesce) {
// Not allowed to coalesce if this set
currentAction++;
+ } else if (at == containerAction) {
+ // Not allowed to coalesce container actions
+ currentAction++;
} else if (at == removeAction) {
if ((lengthData == 1) || (lengthData == 2)){
if ((position + lengthData) == actPrevious.position) {
@@ -862,6 +865,11 @@ void CellBuffer::EndUndoAction() {
uh.EndUndoAction();
}
+void CellBuffer::AddUndoAction(int token) {
+ bool startSequence;
+ uh.AppendAction(containerAction, token, 0, 0, startSequence);
+}
+
void CellBuffer::DeleteUndoHistory() {
uh.DeleteUndoHistory();
}
diff --git a/src/CellBuffer.h b/src/CellBuffer.h
index 4b83f48e0..6cf8ad056 100644
--- a/src/CellBuffer.h
+++ b/src/CellBuffer.h
@@ -83,7 +83,7 @@ public:
int LineFromHandle(int markerHandle);
};
-enum actionType { insertAction, removeAction, startAction };
+enum actionType { insertAction, removeAction, startAction, containerAction };
/**
* Actions are used to store all the information required to perform one undo/redo step.
@@ -213,6 +213,7 @@ public:
bool IsCollectingUndo();
void BeginUndoAction();
void EndUndoAction();
+ void AddUndoAction(int token);
void DeleteUndoHistory();
/// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is
diff --git a/src/Document.cxx b/src/Document.cxx
index 611da25a0..e5913ad98 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -503,21 +503,27 @@ int Document::Undo() {
if (action.at == removeAction) {
NotifyModified(DocModification(
SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));
+ } else if (action.at == containerAction) {
+ DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO);
+ dm.token = action.position;
+ NotifyModified(dm);
} else {
NotifyModified(DocModification(
SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
}
cb.PerformUndoStep();
int cellPosition = action.position;
- ModifiedAt(cellPosition);
- newPos = cellPosition;
+ if (action.at != containerAction) {
+ 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 {
+ } else if (action.at == insertAction) {
modFlags |= SC_MOD_DELETETEXT;
}
if (steps > 1)
@@ -558,19 +564,25 @@ int Document::Redo() {
if (action.at == insertAction) {
NotifyModified(DocModification(
SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));
+ } else if (action.at == containerAction) {
+ DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_REDO);
+ dm.token = action.position;
+ NotifyModified(dm);
} else {
NotifyModified(DocModification(
SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
}
cb.PerformRedoStep();
- ModifiedAt(action.position);
- newPos = action.position;
+ if (action.at != containerAction) {
+ ModifiedAt(action.position);
+ newPos = action.position;
+ }
int modFlags = SC_PERFORMED_REDO;
if (action.at == insertAction) {
newPos += action.lenData;
modFlags |= SC_MOD_INSERTTEXT;
- } else {
+ } else if (action.at == removeAction) {
modFlags |= SC_MOD_DELETETEXT;
}
if (steps > 1)
diff --git a/src/Document.h b/src/Document.h
index 0457b475b..2e8c43eeb 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -173,6 +173,7 @@ public:
bool IsCollectingUndo() { return cb.IsCollectingUndo(); }
void BeginUndoAction() { cb.BeginUndoAction(); }
void EndUndoAction() { cb.EndUndoAction(); }
+ void AddUndoAction(int token) { cb.AddUndoAction(token); }
void SetSavePoint();
bool IsSavePoint() { return cb.IsSavePoint(); }
const char *BufferPointer() { return cb.BufferPointer(); }
@@ -288,6 +289,7 @@ public:
int line;
int foldLevelNow;
int foldLevelPrev;
+ int token;
DocModification(int modificationType_, int position_=0, int length_=0,
int linesAdded_=0, const char *text_=0, int line_=0) :
@@ -298,7 +300,8 @@ public:
text(text_),
line(line_),
foldLevelNow(0),
- foldLevelPrev(0) {}
+ foldLevelPrev(0),
+ token(0) {}
DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
modificationType(modificationType_),
@@ -308,7 +311,8 @@ public:
text(act.data),
line(0),
foldLevelNow(0),
- foldLevelPrev(0) {}
+ foldLevelPrev(0),
+ token(0) {}
};
/**
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 7ba26bb53..5d709fe06 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -3961,6 +3961,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
scn.line = mh.line;
scn.foldLevelNow = mh.foldLevelNow;
scn.foldLevelPrev = mh.foldLevelPrev;
+ scn.token = mh.token;
NotifyParent(scn);
}
}
@@ -7635,6 +7636,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_GETEXTRADESCENT:
return vs.extraDescent;
+ case SCI_ADDUNDOACTION:
+ pdoc->AddUndoAction(wParam);
+ break;
+
default:
return DefWndProc(iMessage, wParam, lParam);
}