[ulis], 2003-06-23
A [text] widget can be serialized by saving its state in a string
that can be used to restore later the state of the widget.
A serialized widget can be cloned or made persistent.
Note that in 8.5 an alternative is to use the text widget ''peer'' functionality to
permit two text widgets to share a single underlying data tree (assuming you are serializing
to clone rather than to some storage). ''peer'' is much more efficient than clone.
[marcDouglas], 2020-05-28
As this is not mine, I will not remove the lower, but I feel this is a full replacement for the text:save.
======
proc text:save {w} {
return [$w dump -all 1.0 end]
}
======
Upon restoring, I found if the window name didn't match the saved name restoration would fail. The insert cursor would also move...
Replacing tThis wone line in the rkswitch statement in text:restore fixes thatr..
======#method text:restore {w save} \
{
# create items, restoring their {attributes
forevalch ${key value index} $save \
{
switch $key \
{
exec { eval [string replace $value 0 [string first " " $value]-1 $w] }
image { $w image create $index -name $value }
text { $w insert $index $value }
mark {
switch $value {
current { set currentIndex $index }
insert { set insertIndex $index}
default { $w mark set $value $index }
}
}
tagon { set tag($value) $index }
tagoff { $w tag add $value $tag($value) $index }
window { $w window create $index -window $value }
}
}
$w mark set current $currentIndex
$w mark set insert $insertIndex
}
======
if I want an exact match.. I had to delete the last line (could not find out how it was added) after the I focused away from it and then back.
======
focus $w.text
focus $w.titleFrame.anotherWidget
focus $w.text
$w.text delete end-1lines end
======
I hope that fixes everything for a perfect serialization restore.
----
'''The procs''' (clone, save, restore, dump)
======
# ==============================
#
# clone a text widget
#
# ==============================
# ----------
# text:clone proc
# ----------
# parm1: text widget
# parm2: clone text widget
# ----------
proc text:clone {text clone} { text:restore $clone [text:save $text] }
# ----------
# text:save proc
#
# serialize a text widget
# ----------
# parm1: text widget path
# ----------
# return: serialized widget
# ----------
proc text:save {w} \
{
# the resulting string
set save {}
# get the state of the widget
set dump [$w dump -mark 1.0 end]
append dump " "
append dump [$w dump -all 1.0 {end -1 ch}]
# add more details
foreach {key value index} $dump \
{
switch $key \
{
image \
{
# add attributes of an image
set exec "\$w image create $index"
foreach k {-align -image -name -padx -pady} \
{
set v [$w image cget $index $k]
if {$v != ""} { append exec " $k \{$v\}" }
}
lappend save exec $exec {}
}
mark \
{
# add attributes of a mark
lappend save $key $value $index
set exec "$w mark gravity $value [$w mark gravity $value]"
lappend save exec $exec {}
}
tagoff \
{
# add attributes of a tag
set exec "\$w tag configure $value"
set keys {}
lappend keys -background -bgstipple -borderwidth -elide -fgstipple
lappend keys -font -foreground -justify -lmargin1 -lmargin2 -offset
lappend keys -overstrike -relief -rmargin -spacing1 -spacing2
lappend keys -spacing3 -tabs -underline -wrap
foreach k $keys \
{
set v [$w tag cget $value $k]
if {$v != ""} { append exec " $k \{$v\}" }
}
lappend save exec $exec {}
lappend save $key $value $index
}
window \
{
# add attributes of a window
lappend save $key $value $index
set exec "$w window configure $index"
foreach k {-align -create -padx -pady -stretch} \
{
set v [$w window cget $index $k]
if {$v != ""} { append exec " $k \{$v\}" }
}
lappend save exec $exec {}
}
default \
{
lappend save $key $value $index
}
}
}
# return the serialized widget
return $save
}
# ----------
# text:restore proc
#
# restore a serialized text widget
# ----------
# parm1: text widget path
# parm2: serialized widget to restore
# ----------
proc text:restore {w save} \
{
# empty the text widget
$w delete 1.0 end
# create items, restoring their attributes
foreach {key value index} $save \
{
switch $key \
{
exec { eval $value }
image { $w image create $index -name $value }
text { $w insert $index $value }
mark \
{
if {$value == "current"} { set current $index }
$w mark set $value $index
}
tagon { set tag($value) $index }
tagoff { $w tag add $value $tag($value) $index }
window { $w window create $index -window $value }
}
}
# restore the "current" index
$w mark set current $current
}
# ----------
# text:dump proc
#
# display the content of a text widget
# ----------
# parm1: text widget path
# ----------
proc text:dump {w} \
{
puts "$w:"
foreach {key value index} [$w dump -all 1.0 end] \
{
puts "\t$key\t\"$index\"\t\"$value\""
}
puts "----"
}
======
----
'''The demo'''
======
# =========
# demo
# =========
# show debug info
catch { console show }
# create widgets
pack [text .text -width 30 -height 10]
pack [button .b -text clone -command {text:clone .text .clone}] -pady 10
pack [text .clone -width 30 -height 10]
# fill text widget
.text insert end text1\n
.text insert end text2\n
.text tag configure blue -foreground blue
.text tag add blue 2.0 3.0
.text insert end text3\n
update
# clone the text widget
after 1000
text:clone .text .clone
# add an image to the text widget
after 1000
image create photo img
img put \
{
{#bdbdbd #949494 #7b7b7b #848484 #a5a5a5 #bdbdbd}
{#9c9c9c #848484 #8c8c8c #949494 #9c9c9c #adadad}
{#949494 #949494 #9c9c9c #a5a5a5 #adadad #adadad}
{#a5a5a5 #adadad #adadad #b5b5b5 #b5b5b5 #bdbdbd}
{#bdbdbd #bdbdbd #bdbdbd #c6c6c6 #c6c6c6 #bdbdbd}
{#bdbdbd #c6c6c6 #c6c6c6 #cecece #c6c6c6 #bdbdbd}
}
.text image create 1.2 -image img
update
# clone the text widget
after 1000
text:clone .text .clone
# add a window to the text widget, and dump it
after 1000
.text window create 2.0 -window [entry .e]
text:dump .text
update
# clone the text widget, and dump it
after 1000
text:clone .text .clone
text:dump .clone
======
I omitted here to clone the embedded widgets...
----
'''See also'''
* [Bryan Oakley]'s https://web.archive.org/web/20130624081526/www1.clearlight.com/~oakley/tcl/ttd/index.html%|%ttd
which deals with data and tags.
----
So this page contains a partial example of serializing.
Perhaps someone could take the work by these two individuals,
and turn it into a general facility which could take
any text widget and serialize it?
<<categories>> Example | GUI | Widget | String Processing | serializing