summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2016-06-08 09:38:29 (GMT)
committerfvogel <fvogelnew1@free.fr>2016-06-08 09:38:29 (GMT)
commitabdebd5b836480c1552c478a871c77b4668135ed (patch)
tree35dd45e3587fecbe3682df06441fd4eacf9cbd81
parent940954ce6034eac3de51350f4d546ed7279e7ec9 (diff)
downloadtk-abdebd5b836480c1552c478a871c77b4668135ed.zip
tk-abdebd5b836480c1552c478a871c77b4668135ed.tar.gz
tk-abdebd5b836480c1552c478a871c77b4668135ed.tar.bz2
It is not possible to rely only on the interp result. A list of indices has to be built as a return value to undo/redo because there can be several edits between two separators and all such edits have to report which range of text they changed. Note: this commit does not deal with refcounts, it is very likely wrong in that respect.
-rw-r--r--generic/tkText.c31
-rw-r--r--generic/tkUndo.c26
-rw-r--r--generic/tkUndo.h4
3 files changed, 43 insertions, 18 deletions
diff --git a/generic/tkText.c b/generic/tkText.c
index d101364..60e726f 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -395,8 +395,8 @@ static int DumpSegment(TkText *textPtr, Tcl_Interp *interp,
const char *key, const char *value,
Tcl_Obj *command, const TkTextIndex *index,
int what);
-static int TextEditUndo(TkText *textPtr);
-static int TextEditRedo(TkText *textPtr);
+static int TextEditUndo(TkText *textPtr, Tcl_Obj *rangesObj);
+static int TextEditRedo(TkText *textPtr, Tcl_Obj *rangesObj);
static Tcl_Obj * TextGetText(const TkText *textPtr,
const TkTextIndex *index1,
const TkTextIndex *index2, int visibleOnly);
@@ -5060,7 +5060,7 @@ DumpSegment(
* Undo the last change.
*
* Results:
- * None.
+ * The ranges of text that were changed by the undo operation.
*
* Side effects:
* Apart from manipulating the undo and redo stacks, the state of the
@@ -5071,7 +5071,8 @@ DumpSegment(
static int
TextEditUndo(
- TkText *textPtr) /* Overall information about text widget. */
+ TkText *textPtr, /* Overall information about text widget. */
+ Tcl_Obj *rangesObj) /* Ranges of text that were changed. */
{
int status;
@@ -5090,7 +5091,7 @@ TextEditUndo(
textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_UNDO;
}
- status = TkUndoRevert(textPtr->sharedTextPtr->undoStack);
+ status = TkUndoRevert(textPtr->sharedTextPtr->undoStack, rangesObj);
if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
@@ -5108,7 +5109,7 @@ TextEditUndo(
* Redo the last undone change.
*
* Results:
- * None.
+ * The ranges of text that were changed by the undo operation.
*
* Side effects:
* Apart from manipulating the undo and redo stacks, the state of the
@@ -5119,7 +5120,8 @@ TextEditUndo(
static int
TextEditRedo(
- TkText *textPtr) /* Overall information about text widget. */
+ TkText *textPtr, /* Overall information about text widget. */
+ Tcl_Obj *rangesObj) /* Ranges of text that were changed. */
{
int status;
@@ -5138,7 +5140,7 @@ TextEditRedo(
textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_REDO;
}
- status = TkUndoApply(textPtr->sharedTextPtr->undoStack);
+ status = TkUndoApply(textPtr->sharedTextPtr->undoStack, rangesObj);
if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
@@ -5174,6 +5176,7 @@ TextEditCmd(
int index, setModified, oldModified;
int canRedo = 0;
int canUndo = 0;
+ Tcl_Obj *rangesObj = Tcl_NewObj();
static const char *const editOptionStrings[] = {
"canundo", "canredo", "modified", "redo", "reset", "separator",
@@ -5257,11 +5260,13 @@ TextEditCmd(
return TCL_ERROR;
}
canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
- if (TextEditRedo(textPtr)) {
+ if (TextEditRedo(textPtr, rangesObj)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to redo", -1));
Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_REDO", NULL);
return TCL_ERROR;
- }
+ } else {
+ Tcl_SetObjResult(interp, rangesObj);
+ }
canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
if (!canUndo || !canRedo) {
GenerateUndoStackEvent(textPtr);
@@ -5292,11 +5297,13 @@ TextEditCmd(
return TCL_ERROR;
}
canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
- if (TextEditUndo(textPtr)) {
+ if (TextEditUndo(textPtr, rangesObj)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to undo", -1));
Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_UNDO", NULL);
return TCL_ERROR;
- }
+ } else {
+ Tcl_SetObjResult(interp, rangesObj);
+ }
canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
if (!canRedo || !canUndo) {
GenerateUndoStackEvent(textPtr);
diff --git a/generic/tkUndo.c b/generic/tkUndo.c
index c66905d..f364326 100644
--- a/generic/tkUndo.c
+++ b/generic/tkUndo.c
@@ -556,7 +556,8 @@ TkUndoInsertUndoSeparator(
* Undo a compound action on the stack.
*
* Results:
- * A Tcl status code
+ * A Tcl status code. Also, the passed Tcl_(List)Obj is appended by the
+ * interp results from evaluation of each element of the undo stack.
*
* Side effects:
* None.
@@ -566,7 +567,8 @@ TkUndoInsertUndoSeparator(
int
TkUndoRevert(
- TkUndoRedoStack *stack)
+ TkUndoRedoStack *stack,
+ Tcl_Obj *retObj)
{
TkUndoAtom *elem;
@@ -598,6 +600,13 @@ TkUndoRevert(
EvaluateActionList(stack->interp, elem->revert);
+ /*
+ * The interp result is appended to the returned object for each
+ * element of the undo stack (not for each sub-atom).
+ */
+
+ Tcl_ListObjAppendList(NULL, retObj, Tcl_GetObjResult(stack->interp));
+
TkUndoPushStack(&stack->redoStack, elem);
elem = TkUndoPopStack(&stack->undoStack);
}
@@ -619,7 +628,8 @@ TkUndoRevert(
* Redo a compound action on the stack.
*
* Results:
- * A Tcl status code
+ * A Tcl status code. Also, the passed Tcl_(List)Obj is appended by the
+ * interp results from evaluation of each element of the redo stack.
*
* Side effects:
* None.
@@ -629,7 +639,8 @@ TkUndoRevert(
int
TkUndoApply(
- TkUndoRedoStack *stack)
+ TkUndoRedoStack *stack,
+ Tcl_Obj *retObj)
{
TkUndoAtom *elem;
@@ -660,6 +671,13 @@ TkUndoApply(
EvaluateActionList(stack->interp, elem->apply);
+ /*
+ * The interp result is appended to the returned object for each
+ * element of the redo stack (not for each sub-atom).
+ */
+
+ Tcl_ListObjAppendList(NULL, retObj, Tcl_GetObjResult(stack->interp));
+
TkUndoPushStack(&stack->undoStack, elem);
elem = TkUndoPopStack(&stack->redoStack);
}
diff --git a/generic/tkUndo.h b/generic/tkUndo.h
index 490ede9..505e0f0 100644
--- a/generic/tkUndo.h
+++ b/generic/tkUndo.h
@@ -109,7 +109,7 @@ MODULE_SCOPE TkUndoSubAtom *TkUndoMakeSubAtom(TkUndoProc *funcPtr,
TkUndoSubAtom *subAtomList);
MODULE_SCOPE void TkUndoPushAction(TkUndoRedoStack *stack,
TkUndoSubAtom *apply, TkUndoSubAtom *revert);
-MODULE_SCOPE int TkUndoRevert(TkUndoRedoStack *stack);
-MODULE_SCOPE int TkUndoApply(TkUndoRedoStack *stack);
+MODULE_SCOPE int TkUndoRevert(TkUndoRedoStack *stack, Tcl_Obj *retObj);
+MODULE_SCOPE int TkUndoApply(TkUndoRedoStack *stack, Tcl_Obj *retObj);
#endif /* _TKUNDO */