summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2016-05-12 21:12:30 (GMT)
committerfvogel <fvogelnew1@free.fr>2016-05-12 21:12:30 (GMT)
commitfb21de2b2d966342327edfe777b99bad3c00db21 (patch)
treed7ebe8524aa6dbe63f0038497932d857aede64a0
parent0c494bd4742fae9dc0782b5ec7f3dfcbe7c9869f (diff)
downloadtk-fb21de2b2d966342327edfe777b99bad3c00db21.zip
tk-fb21de2b2d966342327edfe777b99bad3c00db21.tar.gz
tk-fb21de2b2d966342327edfe777b99bad3c00db21.tar.bz2
Added <<UndoStack>> event, triggering when either the undo stack or the redo stack becomes empty or unempty
-rw-r--r--generic/tkText.c74
1 files changed, 63 insertions, 11 deletions
diff --git a/generic/tkText.c b/generic/tkText.c
index 4a352b2..5522154 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -401,6 +401,7 @@ static Tcl_Obj * TextGetText(const TkText *textPtr,
const TkTextIndex *index1,
const TkTextIndex *index2, int visibleOnly);
static void GenerateModifiedEvent(TkText *textPtr);
+static void GenerateUndoStackEvent(TkText *textPtr);
static void UpdateDirtyFlag(TkSharedText *sharedPtr);
static void RunAfterSyncCmd(ClientData clientData);
static void TextPushUndoAction(TkText *textPtr,
@@ -2769,6 +2770,7 @@ TextPushUndoAction(
/* Index describing second location. */
{
TkUndoSubAtom *iAtom, *dAtom;
+ TkUndoAtom *redoElem, *undoElem;
/*
* Create the helpers.
@@ -2855,6 +2857,9 @@ TextPushUndoAction(
Tcl_DecrRefCount(index1Obj);
Tcl_DecrRefCount(index2Obj);
+ undoElem = textPtr->sharedTextPtr->undoStack->undoStack;
+ redoElem = textPtr->sharedTextPtr->undoStack->redoStack;
+
/*
* Depending whether the action is to insert or delete, we provide the
* appropriate second and third arguments to TkUndoPushAction. (The first
@@ -2866,6 +2871,10 @@ TextPushUndoAction(
} else {
TkUndoPushAction(textPtr->sharedTextPtr->undoStack, dAtom, iAtom);
}
+
+ if (undoElem == NULL || redoElem != NULL) {
+ GenerateUndoStackEvent(textPtr);
+ }
}
/*
@@ -5155,6 +5164,10 @@ TextEditCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
int index, setModified, oldModified;
+ int canRedo = 0;
+ int canUndo = 0;
+ TkUndoAtom *redoElem, *undoElem;
+
static const char *const editOptionStrings[] = {
"canundo", "canredo", "modified", "redo", "reset", "separator",
"undo", NULL
@@ -5175,9 +5188,7 @@ TextEditCmd(
}
switch ((enum editOptions) index) {
- case EDIT_CANREDO: {
- int canRedo = 0;
-
+ case EDIT_CANREDO:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
@@ -5187,10 +5198,7 @@ TextEditCmd(
}
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canRedo));
break;
- }
- case EDIT_CANUNDO: {
- int canUndo = 0;
-
+ case EDIT_CANUNDO:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
@@ -5200,7 +5208,6 @@ TextEditCmd(
}
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canUndo));
break;
- }
case EDIT_MODIFIED:
if (objc == 3) {
Tcl_SetObjResult(interp,
@@ -5241,22 +5248,32 @@ TextEditCmd(
}
break;
case EDIT_REDO:
- if (objc != 3) {
+ if (objc != 3) {
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
- if (TextEditRedo(textPtr)) {
+ undoElem = textPtr->sharedTextPtr->undoStack->undoStack;
+ if (TextEditRedo(textPtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to redo", -1));
Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_REDO", NULL);
return TCL_ERROR;
}
+ redoElem = textPtr->sharedTextPtr->undoStack->redoStack;
+ if (undoElem == NULL || redoElem == NULL) {
+ GenerateUndoStackEvent(textPtr);
+ }
break;
case EDIT_RESET:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
+ undoElem = textPtr->sharedTextPtr->undoStack->undoStack;
+ redoElem = textPtr->sharedTextPtr->undoStack->redoStack;
TkUndoClearStacks(textPtr->sharedTextPtr->undoStack);
+ if (undoElem != NULL || redoElem != NULL) {
+ GenerateUndoStackEvent(textPtr);
+ }
break;
case EDIT_SEPARATOR:
if (objc != 3) {
@@ -5266,15 +5283,20 @@ TextEditCmd(
TkUndoInsertUndoSeparator(textPtr->sharedTextPtr->undoStack);
break;
case EDIT_UNDO:
- if (objc != 3) {
+ if (objc != 3) {
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
+ redoElem = textPtr->sharedTextPtr->undoStack->redoStack;
if (TextEditUndo(textPtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to undo", -1));
Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_UNDO", NULL);
return TCL_ERROR;
}
+ undoElem = textPtr->sharedTextPtr->undoStack->undoStack;
+ if (redoElem == NULL || undoElem == NULL) {
+ GenerateUndoStackEvent(textPtr);
+ }
break;
}
return TCL_OK;
@@ -5390,6 +5412,36 @@ GenerateModifiedEvent(
/*
*----------------------------------------------------------------------
*
+ * GenerateUndoStackEvent --
+ *
+ * Send an event that the undo or redo stack became empty or unempty.
+ * This is equivalent to:
+ * event generate $textWidget <<UndoStack>>
+ * for all peers of $textWidget.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * May force the text window (and all peers) into existence.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GenerateUndoStackEvent(
+ TkText *textPtr) /* Information about text widget. */
+{
+ for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL;
+ textPtr = textPtr->next) {
+ Tk_MakeWindowExist(textPtr->tkwin);
+ TkSendVirtualEvent(textPtr->tkwin, "UndoStack", NULL);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* UpdateDirtyFlag --
*
* Updates the dirtyness of the text widget