summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/text.n12
-rw-r--r--generic/tkText.c34
-rw-r--r--generic/tkUndo.c67
-rw-r--r--generic/tkUndo.h3
-rw-r--r--tests/text.test28
5 files changed, 136 insertions, 8 deletions
diff --git a/doc/text.n b/doc/text.n
index 9ec8f74..cb08d2f 100644
--- a/doc/text.n
+++ b/doc/text.n
@@ -1295,6 +1295,12 @@ When the \fB\-undo\fR option is true, reapplies the last undone edits provided
no other edits were done since then. Generates an error when the redo stack is
empty. Does nothing when the \fB\-undo\fR option is false.
.TP
+\fIpathName \fBedit redodepth\fR
+.
+Returns the depth of the redo stack (number of redoable actions). When this is
+zero there is nothing to redo. When the \fB\-undo\fR option is false zero is
+returned.
+.TP
\fIpathName \fBedit reset\fR
.
Clears the undo and redo stacks.
@@ -1310,6 +1316,12 @@ Undoes the last edit action when the \fB\-undo\fR option is true. An edit
action is defined as all the insert and delete commands that are recorded on
the undo stack in between two separators. Generates an error when the undo
stack is empty. Does nothing when the \fB\-undo\fR option is false.
+.TP
+\fIpathName \fBedit undodepth\fR
+.
+Returns the depth of the undo stack (number of undoable actions). When this is
+zero there is nothing to undo. When the \fB\-undo\fR option is false zero is
+returned.
.RE
.TP
\fIpathName \fBget\fR ?\fB\-displaychars\fR? ?\fB\-\-\fR? \fIindex1\fR ?\fIindex2 ...\fR?
diff --git a/generic/tkText.c b/generic/tkText.c
index 3e8d625..d611323 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -2093,7 +2093,7 @@ ConfigureText(
textPtr->sharedTextPtr->maxUndo = textPtr->maxUndo;
textPtr->sharedTextPtr->autoSeparators = textPtr->autoSeparators;
- TkUndoSetDepth(textPtr->sharedTextPtr->undoStack,
+ TkUndoSetMaxDepth(textPtr->sharedTextPtr->undoStack,
textPtr->sharedTextPtr->maxUndo);
/*
@@ -5156,10 +5156,12 @@ TextEditCmd(
{
int index, setModified, oldModified;
static const char *const editOptionStrings[] = {
- "modified", "redo", "reset", "separator", "undo", NULL
+ "modified", "redo", "redodepth", "reset", "separator", "undo",
+ "undodepth", NULL
};
enum editOptions {
- EDIT_MODIFIED, EDIT_REDO, EDIT_RESET, EDIT_SEPARATOR, EDIT_UNDO
+ EDIT_MODIFIED, EDIT_REDO, EDIT_REDODEPTH, EDIT_RESET,
+ EDIT_SEPARATOR, EDIT_UNDO, EDIT_UNDODEPTH
};
if (objc < 3) {
@@ -5223,6 +5225,19 @@ TextEditCmd(
return TCL_ERROR;
}
break;
+ case EDIT_REDODEPTH: {
+ int depth = 0;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ if (textPtr->sharedTextPtr->undo) {
+ depth = TkUndoGetDepth(textPtr->sharedTextPtr->undoStack, 1);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(depth));
+ break;
+ }
case EDIT_RESET:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 3, objv, NULL);
@@ -5248,6 +5263,19 @@ TextEditCmd(
return TCL_ERROR;
}
break;
+ case EDIT_UNDODEPTH: {
+ int depth = 0;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ if (textPtr->sharedTextPtr->undo) {
+ depth = TkUndoGetDepth(textPtr->sharedTextPtr->undoStack, 0);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(depth));
+ break;
+ }
}
return TCL_OK;
}
diff --git a/generic/tkUndo.c b/generic/tkUndo.c
index 8359e0a..3aa3ee2 100644
--- a/generic/tkUndo.c
+++ b/generic/tkUndo.c
@@ -353,7 +353,7 @@ TkUndoInitStack(
/*
*----------------------------------------------------------------------
*
- * TkUndoSetDepth --
+ * TkUndoSetMaxDepth --
*
* Set the maximum depth of stack.
*
@@ -368,7 +368,7 @@ TkUndoInitStack(
*/
void
-TkUndoSetDepth(
+TkUndoSetMaxDepth(
TkUndoRedoStack *stack, /* An Undo/Redo stack */
int maxdepth) /* The maximum stack depth */
{
@@ -428,6 +428,67 @@ TkUndoSetDepth(
/*
*----------------------------------------------------------------------
*
+ * TkUndoGetDepth
+ *
+ * Return the depth of the undo (or redo) stack.
+ *
+ * Results:
+ * An integer representing the number of undoable (or redoable) actions.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkUndoGetDepth(
+ TkUndoRedoStack *stack, /* An Undo/Redo stack */
+ int whichStack) /* 0 means the undo stack,
+ * otherwise the redo stack */
+{
+ int depth = 0;
+ TkUndoAtom *elem = NULL;
+
+ if (stack != NULL) {
+ if (whichStack) {
+ elem = stack->redoStack;
+ } else {
+ elem = stack->undoStack;
+ }
+
+ if (elem != NULL) {
+ /*
+ * Skip the first (top) separator if there is one.
+ */
+
+ if (elem->type == TK_UNDO_SEPARATOR) {
+ elem = elem->next;
+ }
+
+ /*
+ * The number of compound actions in the stack is then
+ * the number of separators plus one, except if there is
+ * a separator at the bottom of the stack. This latter
+ * case cannot however happen (TkUndoInsertSeparator
+ * prevents from inserting a separator there).
+ */
+
+ while (elem != NULL) {
+ if (elem->type == TK_UNDO_SEPARATOR) {
+ depth++;
+ }
+ elem = elem->next;
+ }
+ depth++;
+ }
+ }
+ return depth;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkUndoClearStacks --
*
* Clear both the undo and redo stack.
@@ -498,7 +559,7 @@ TkUndoInsertUndoSeparator(
{
if (TkUndoInsertSeparator(&stack->undoStack)) {
stack->depth++;
- TkUndoSetDepth(stack, stack->maxdepth);
+ TkUndoSetMaxDepth(stack, stack->maxdepth);
}
}
diff --git a/generic/tkUndo.h b/generic/tkUndo.h
index e63aac4..883f6ee 100644
--- a/generic/tkUndo.h
+++ b/generic/tkUndo.h
@@ -96,7 +96,8 @@ MODULE_SCOPE void TkUndoClearStack(TkUndoAtom **stack);
*/
MODULE_SCOPE TkUndoRedoStack *TkUndoInitStack(Tcl_Interp *interp, int maxdepth);
-MODULE_SCOPE void TkUndoSetDepth(TkUndoRedoStack *stack, int maxdepth);
+MODULE_SCOPE void TkUndoSetMaxDepth(TkUndoRedoStack *stack, int maxdepth);
+MODULE_SCOPE int TkUndoGetDepth(TkUndoRedoStack *stack, int whichStack);
MODULE_SCOPE void TkUndoClearStacks(TkUndoRedoStack *stack);
MODULE_SCOPE void TkUndoFreeStack(TkUndoRedoStack *stack);
MODULE_SCOPE void TkUndoInsertUndoSeparator(TkUndoRedoStack *stack);
diff --git a/tests/text.test b/tests/text.test
index f217bcf..56e69c0 100644
--- a/tests/text.test
+++ b/tests/text.test
@@ -6207,7 +6207,7 @@ test text-27.2 {TextEditCmd procedure, argument parsing} -body {
.t edit gorp
} -cleanup {
destroy .t
-} -returnCodes {error} -result {bad edit option "gorp": must be modified, redo, reset, separator, or undo}
+} -returnCodes {error} -result {bad edit option "gorp": must be modified, redo, redodepth, reset, separator, undo, or undodepth}
test text-27.3 {TextEditUndo procedure, undoing changes} -body {
text .t -undo 1
pack .t
@@ -6494,6 +6494,32 @@ test text-27.22 {patch 1669632 (v) - <<Clear>> is atomic} -setup {
} -cleanup {
destroy .top.t .top
} -result "This A an example text"
+test text-27.24 {TextEditCmd procedure, undo and redo stack depths} -setup {
+ destroy .t
+ set res {}
+} -body {
+ text .t -undo false -autoseparators false
+ lappend res [.t edit undodepth] [.t edit redodepth]
+ .t configure -undo true
+ lappend res [.t edit undodepth] [.t edit redodepth]
+ .t insert end "DO\n"
+ .t edit separator
+ .t insert end "IT\n"
+ .t insert end "YOURSELF\n"
+ .t edit separator
+ lappend res [.t edit undodepth] [.t edit redodepth]
+ .t edit undo
+ lappend res [.t edit undodepth] [.t edit redodepth]
+ .t configure -undo false
+ lappend res [.t edit undodepth] [.t edit redodepth]
+ .t configure -undo true
+ lappend res [.t edit undodepth] [.t edit redodepth]
+ .t edit redo
+ lappend res [.t edit undodepth] [.t edit redodepth]
+} -cleanup {
+ destroy .t
+} -result {0 0 0 0 2 0 1 1 0 0 1 1 2 0}
+
test text-28.1 {bug fix - 624372, ControlUtfProc long lines} -body {
pack [text .t -wrap none]