Author: François Vogel <fvogelnew1@free.fr>
State: Final
Type: Project
Vote: Done
Created: 05-Apr-2016
Post-History:
Keywords: Tk
Tcl-Version: 8.6.6
Abstract
Tk features a generic undo/redo mechanism (see [104]). This is used in practice by the text widget, within the edit command. The present TIP proposes to add two new subcommands to the edit command allowing the user to know whether undo and redo is possible for a text widget.
Rationale
The undo/redo feature of Tk is handy and works very well. In modern GUIs, there is usually a button in a menubar to call the "Undo" command, and likewise for "Redo". It is good practice to enhance the user experience by greying out or otherwise changing the button aspect when there is nothing to undo (or redo). This cannot be achieved currently with the curent Tk implementation because there is no way to know whether the undo and redo stacks are empty or not.
This feature was requested for the text widget in RFE 1273358 https://core.tcl.tk/tk/tktview/1273358
Proposed Change
It is proposed to add the following subcommands to the text widget's edit command:
canundo:
Returns a boolean true if undo is possible, i.e. when the undo stack is not empty. Otherwise returns false.
canredo:
Returns a boolean true if redo is possible, i.e. when the undo stack is not empty. Otherwise returns false.
When the -undo option of the text widget is false both subcommands return false since indeed no undo nor redo action is possible in this case. The undo/redo stacks are however not cleared, so that when -undo becomes eventually true again the two new subcommands will return their value in accordance with the contents of the stacks (this is current behavior of the undo/redo feature - the TIP does not intend to change this).
This new capability will be implemented in the generic code for undo (generic/tkUndo.c), so that any client of the generic undo/redo mechanism can make use of it. Currently, only the text widget is concerned since no other Tk widget is featuring undo/redo.
Besides the two new subcommands, it is also proposed to add a new virtual event
<
Despite this is a new feature, this TIP targets Tk 8.6.6 since no change of any existing behavior is proposed: only new, additonal, features are proposed. It is therefore believed there is no risk regarding backwards compatibility in the 8.6.x series.
Example
package require Tk
pack [text .t -undo false -autoseparators false]
set nbUS 0
bind .t <<UndoStack>> {incr nbUS}
.t edit canundo ; # 0
.t edit canredo ; # 0
.t configure -undo true
.t edit canundo ; # 0
.t edit canredo ; # 0
.t insert end "ABC\n"
.t edit separator
.t insert end "DEF\n"
.t insert end "DEF again\n"
.t edit separator
.t edit canundo ; # 1
.t edit canredo ; # 0
.t edit undo
.t edit canundo ; # 1
.t edit canredo ; # 1
# A quick interactive testing environment...:
pack [label .l]
proc showit {} {
global nbUS
.l configure -text "Can undo: [.t edit canundo]\t\t\t \
Can redo: [.t edit canredo]\t\t\t \
<<UndoStack>> triggered: $nbUS"
after 200 showit
}
showit
proc toggleautosep {} {
global autosepset
set autosepset [.t cget -autoseparators]
if {$autosepset} {
.t configure -autoseparators false
} else {
.t configure -autoseparators true
}
set autosepset [.t cget -autoseparators]
}
proc toggleundo {} {
global undoset
set undoset [.t cget -undo]
if {$undoset} {
.t configure -undo false
} else {
.t configure -undo true
}
set undoset [.t cget -undo]
}
button .b1 -text "Insert separator" -command {.t edit separator}
button .b2 -text "Undo" -command {.t edit undo}
button .b3 -text "Redo" -command {.t edit redo}
button .b32 -text "Reset" -command {.t edit reset}
checkbutton .b4 -text "-autoseparators" -command toggleautosep -variable autosepset
checkbutton .b5 -text "-undo" -command toggleundo -variable undoset ; .b5 select
pack .b1 .b2 .b3 .b32 .b4 .b5 -side left -padx 10
Reference Implementation
A reference implementation is available in branch tip-446 of the fossil
repository. Credits for this implementation largely go to Neil Hodgson, the author of TkTextPlus (for canundo/canredo) and to Koen Danckaert (for <
Copyright
This document has been placed in the public domain.