diff options
author | fvogel <fvogelnew1@free.fr> | 2016-07-04 21:26:53 (GMT) |
---|---|---|
committer | fvogel <fvogelnew1@free.fr> | 2016-07-04 21:26:53 (GMT) |
commit | 77f4d07ef5cfb838fee58aeadf50fa3d948d273d (patch) | |
tree | 2b5a79941dc2149d7daa378cdc78eb5777d03ce6 /library | |
parent | e18f6a2c8b606211bc86468f27e753a239a3c5dc (diff) | |
download | tk-77f4d07ef5cfb838fee58aeadf50fa3d948d273d.zip tk-77f4d07ef5cfb838fee58aeadf50fa3d948d273d.tar.gz tk-77f4d07ef5cfb838fee58aeadf50fa3d948d273d.tar.bz2 |
Return indices making sense at undo/redo return time. The returned ranges are optimized (no duplicates, no overlapping ranges). Works but needs polishing.
Diffstat (limited to 'library')
-rw-r--r-- | library/text.tcl | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/library/text.tcl b/library/text.tcl index 2bf1b2b..cc78bc2 100644 --- a/library/text.tcl +++ b/library/text.tcl @@ -1202,3 +1202,70 @@ proc ::tk::TextScanDrag {w x y} { $w scan dragto $x $y } } + +# ::tk::TextUndoRedoProcessMarks -- +# +# This proc is executed after an undo or redo action. +# It processes the list of undo/redo marks temporarily set in the +# text widget to positions delimiting where changes happened, and +# returns a flat list of ranges. The temporary marks are removed +# from the text widget. +# +# Arguments: +# w - The text widget + +proc ::tk::TextUndoRedoProcessMarks {w} { + set indices {} + set undoMarks {} + # only consider the temporary marks set by an undo/redo action + foreach mark [$w mark names] { + if {[string range $mark 0 11] eq "tk::undoMark"} { + lappend undoMarks $mark + } + } + # the number of undo/redo marks is always even + set nUndoMarks [llength $undoMarks] + set n [expr {$nUndoMarks / 2}] + set undoMarks [lsort -dictionary $undoMarks] + set Lmarks [lrange $undoMarks 0 [expr {$n - 1}]] + set Rmarks [lrange $undoMarks $n [llength $undoMarks]] + foreach Lmark $Lmarks Rmark $Rmarks { + lappend indices [$w index $Lmark] [$w index $Rmark] + $w mark unset $Lmark $Rmark + } +#puts "Unoptimized indices: $indices" + # process ranges to: + # - remove those already fully included in another range + # - merge overlapping ranges + set ind [lsort -dictionary -stride 2 $indices] + set indices {} + for {set i 0} {$i < $nUndoMarks} {incr i 2} { + set il1 [lindex $ind $i] + set ir1 [lindex $ind [expr {$i + 1}]] + lappend indices $il1 $ir1 +#puts " range1: $il1 $ir1" + for {set j [expr {$i + 2}]} {$j < $nUndoMarks} {incr j 2} { + set il2 [lindex $ind $j] + set ir2 [lindex $ind [expr {$j + 1}]] +#puts " range2: $il2 $ir2" + if {[$w compare $il2 > $ir1]} { + # second range starts after the end of first range + set j $nUndoMarks + } else { + if {[$w compare $ir2 > $ir1]} { + # second range overlaps with first range + set indices [lreplace $indices end-1 end] + lappend indices $il1 $ir2 + } else { + # second range is fully included in first range + } + set ind [lreplace $ind $j [expr {$j + 1}]] + incr j -2 + incr nUndoMarks -2 + } +#puts " indices: $indices" + } + } +#puts "OPTIMIZED indices: $indices" + return $indices +} |