X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?p=ypp-sc-tools.main.git;a=blobdiff_plain;f=pctb%2Fdictionary-manager;h=10218e0a6acbbd9a12627c0c7ea625a6c084ef18;hp=c2ea2b59f5b371fe99d72de6afa30b27123c468b;hb=f2358d0ea7b40ba405621947513f48108ca93504;hpb=f8488ba218ce448dc5c02c8d83e85b6c551332eb diff --git a/pctb/dictionary-manager b/pctb/dictionary-manager index c2ea2b5..10218e0 100755 --- a/pctb/dictionary-manager +++ b/pctb/dictionary-manager @@ -25,6 +25,10 @@ # sponsored by Three Rings. +# ./dictionary-manager --approve-updates ijackson@login.chiark.greenend.org.uk /home/ijackson/things/ypp-sc-tools.pctb-dict-test/pctb /home/ftp/users/ijackson/pctb/test +# ./dictionary-manager --approve-updates ijackson@login.chiark.greenend.org.uk /home/ijackson/things/ypp-sc-tools.pctb-dict/pctb /home/ftp/users/ijackson/pctb + + # invocation: # OUT OF DATE # run this without args @@ -71,6 +75,12 @@ proc puts_counted {f dvar} { debug "PUTS_COUNTED $count $dvar" } +proc bgerror {m} { + global errorCode errorInfo + puts stderr "ERROR: $m\n[list $errorCode]\n$errorInfo\n"; + exit 16 +} + #---------- display core ---------- set mul 6 @@ -89,12 +99,12 @@ proc init_widgets {} { frame .privacy -bd 2 -relief groove pack .privacy -side top -padx 2 -pady 2 -fill x - upload_init_widgets + upload_init frame .d -bd 2 -relief groove -pady 2 -padx 2 image create bitmap image/main - label .d.mi -image image/main -borderwidth 0 + label .d.mi -image image/main -bd 0 frame .d.csr -bg black -height $csrh frame .d.got -bg black -height $gotsh @@ -113,6 +123,7 @@ static unsigned char csr_bits[] = { entry .d.csr.csr.e -bd 0 pack .d.csr.csr.l -side left + frame .d.selctx -bd 2 -relief groove frame .d.mi.csr_0 -bg white -width 1 frame .d.mi.csr_1 -bg white -width 1 frame .d.pe @@ -129,7 +140,7 @@ static unsigned char csr_bits[] = { } proc resize_widgets_core {} { - global mulcols mulrows csrh gotsh ctxh glyphsdone + global mulcols mulrows csrh gotsh ctxh global unk_l unk_contexts foreach w {.d.csr .d.got .d.ctx} { @@ -159,12 +170,14 @@ proc helptext {t} { proc bind_key {k proc} { global keybindings - bind . $proc + bind .d $proc set keybindings($k) [expr {!![string length $proc]}] + .d configure -takefocus 1 } proc unbind_all_keys {} { global keybindings foreach k [array names keybindings] { bind_key $k {} } + .d configure -takefocus 0 } #---------- database read and write common wrapper ---------- @@ -218,8 +231,22 @@ proc write_database {} { file rename -force $database_fn.new $database_fn } +proc select_database {dbname_spec} { + global dbname + set dbname $dbname_spec + read_database "./#local-$dbname#.txt" +} + +proc do_database_update {im def} { + global database + maybe_upload_entry $im $def + set database($im) $def + write_database +} + proc required/char {} { - global mulrows glyphsdone unk_l unk_r unk_contexts rows + global mulrows glyphsdone unk_l unk_r unk_contexts rows new_context + global all_contexts must_gets stdin l @@ -229,25 +256,55 @@ proc required/char {} { char_read_xpm stdin + catch { unset all_contexts } + resize_widgets_core foreach w {0 1} { .d.mi.csr_$w configure -height $mulrows } set maxh 0 - foreach {min max contexts got} $glyphsdone { - show_context maxh $min $contexts + foreach {min max context contexts got} $glyphsdone { + show_context maxh $min $context + foreach ctx $contexts { set all_contexts($ctx) 1 } + } + foreach ctx $unk_contexts { set all_contexts($ctx) 1 } + + eval destroy [winfo children .d.selctx] + label .d.selctx.title -text \ + {Select match context for altering dictionary:} + pack .d.selctx.title -side left + set new_context [lindex $unk_contexts 0] + + set ci 0; foreach ctx [lsort [array names all_contexts]] { + set all_contexts($ctx) $ci + set selw .d.selctx.c$ci + set seltxt $ctx + radiobutton $selw -variable new_context -value $ctx -text $seltxt + pack $selw -side left + incr ci } + $selw configure -text "$seltxt." + label .d.selctx.warning -text {See README.charset.} + pack .d.selctx.warning -side left + show_context maxh $unk_l $unk_contexts .d.ctx configure -height $maxh pack forget .d.pe - pack .d.csr -side top -before .d.mi + pack .d.selctx .d.csr -side top -before .d.mi pack .d.got .d.ctx -side top -after .d.mi + pack configure .d.selctx -fill x + focus .d - read_database "./#local-char$rows#.txt" + select_database char$rows draw_glyphsdone startup_cursor } +proc approve_showentry_xinfo/char {w def} { + set unic [string2unicodenames $def] + label $w -text $unic +} + #========== PIXMAPS ========== #---------- pixmap database read and write ---------- @@ -315,20 +372,23 @@ proc pixmap_maybe_ok {} { } proc pixmap_ok {} { global database ppm pixmap_selcol pixmap_selrow mainkind alloptions + + return_result_start foreach_pixmap_col col { .d.pe.grid.l$col configure -state disabled } .d.pe.ok configure -state disabled - helptext {{{ Processing }}} + manyset [lrange $alloptions [expr {$pixmap_selcol*3}] end] \ colname coldesc rows manyset [lrange $rows [expr {$pixmap_selrow*2}] end] \ rowname rowdesc set result "$colname - $rowname" debug "UPDATE PIXMAP AS >$result<" - set database($ppm) $result - write_database - done/$mainkind + + do_database_update $ppm $result + + return_result_finish } proc required/pixmap {} { @@ -344,9 +404,9 @@ proc required/pixmap {} { set data [exec pnmscale 2 << $ppm] image create photo image/main -data $data - set alloptions [exec ./dictionary-pixmap-options $unk_what] + set alloptions [exec ./database-info-fetch $unk_what] - read_database "./#local-pixmap#.txt" + select_database pixmap set mulcols [image width image/main] set mulrows [image height image/main] @@ -354,8 +414,9 @@ proc required/pixmap {} { place forget .d.mi.csr_0 place forget .d.mi.csr_1 - pack forget .d.csr .d.got + pack forget .d.selctx .d.csr .d.got pack .d.pe -side top -before .d.mi -pady 2 + .d configure -takefocus 0 #-pady 2 -fill x eval destroy [winfo children .d.pe.grid] @@ -379,9 +440,13 @@ proc required/pixmap {} { } } +proc approve_showentry_xinfo/pixmap {w def} { + label $w -image image/empty +} + #========== UPLOADS TO DICTIONARY SERVER ========== -proc upload_init_widgets {} { +proc upload_init {} { global privacy_setting set privacy_setting [upload_status] @@ -414,6 +479,10 @@ proc upload_init_widgets {} { $w configure -state disabled } } + if {$privacy_setting} { + package require http + ::http::config -urlencoding utf-8 + } } proc upload_status {} { @@ -424,11 +493,85 @@ proc upload_status {} { if {![string compare 0 $env(YPPSC_PCTB_DICT_SUBMIT)]} { debug b; return 0 } if {![info exists env(YPPSC_PIRATE)]} { return 1 } + if {![info exists env(YPPSC_OCEAN)]} { return 1 } if {![string length $env(YPPSC_PIRATE)]} { return 1 } + if {![string length $env(YPPSC_OCEAN)]} { return 1 } return 2 } +proc maybe_upload_entry {im def} { + global reqkind privacy_setting env dbname quiet + + debug "DB-UPDATE PRIVACY $privacy_setting" + if {!$privacy_setting} return + + debug "DB-UPDATE UPLOADING" + + set pl {} + lappend pl dict $dbname + + if {$privacy_setting>=2} { + set pirate [string totitle $env(YPPSC_PIRATE)] + set ocean [string totitle $env(YPPSC_OCEAN)] + debug "DB-UPDATE NON-ANON $ocean $pirate" + lappend pl \ + pirate $pirate \ + ocean $ocean + } + lappend pl entry [format_database_entry/$reqkind $im $def] + + set url $env(YPPSC_PCTB_DICT_SUBMIT) + append url dictionary-update-receiver + + set query [eval ::http::formatQuery $pl] + regsub -all {%0d} $query {} query + debug "DB-UPDATE QUERY $query" + + if {[regexp {^\.?/} $url]} { + set cmd [list $url $query] + debug "SUBMIT CMD [string range $cmd 0 200]..." + set body [eval exec $cmd 2>@ stderr] + regsub {^Content-Type: text/plain.*\n\n} $body {} body + } else { + + if {[catch { + set req [::http::geturl $url -query $query] + } emsg]} { + puts stderr \ + "\nWARNING: Cannot do dictionary upload: $emsg\n" + return + } + upvar #0 $req s + debug "DB-UPDATE DONE $req $s(status) [array names s]" + set ncode [::http::ncode $req] + + if {!(![string compare ok $s(status)] && + ![string compare 200 $ncode])} { + set m "\nWARNING: Dictionary upload failed:" + foreach v {status http error posterror} { + if {[info exists s($v)]} { append m "\n $v: $s($v)" } + } + puts stderr $m + return + } + set body $s(body) + ::http::cleanup $req + } + + if {![string match {OK *} $body]} { + set m "\nWARNING: Dictionary upload went wrong:\n" + append m "\n " [join [split $body "\n"] "\n "] + puts stderr $m + return + } + + if {!$quiet} { + puts stderr \ + "Uploaded $dbname `$def': $body" + } +} + #========== CHARACTER SET ========== #---------- xpm input processor ---------- @@ -457,11 +600,11 @@ proc char_read_xpm {f} { set unk_l [expr {$unk_l - $chop_l}] set unk_r [expr {$unk_r - $chop_l}] set ngd {} - foreach {min max contexts got} $glyphsdone { + foreach {min max context contexts got} $glyphsdone { lappend ngd \ [expr {$min-$chop_l}] \ [expr {$max-$chop_l}] \ - $contexts $got + $context $contexts $got } set glyphsdone $ngd @@ -503,7 +646,7 @@ proc char_read_xpm {f} { set how q } else { set ab 0 - foreach {min max contexts got} $glyphsdone { + foreach {min max context contexts got} $glyphsdone { set rhsmost_max $max if {$x >= $min && $x <= $max} { set how [lindex {a b} $ab] @@ -555,7 +698,7 @@ proc show_context {maxhv x ctxs} { proc draw_glyphsdone {} { global glyphsdone mul inter eval destroy [winfo children .d.got] - foreach {min max contexts got} $glyphsdone { + foreach {min max context contexts got} $glyphsdone { frame .d.got.m$min -bd 0 -background \#888 label .d.got.m$min.l -text "$got" -fg white -bg black -bd 0 pack .d.got.m$min.l -padx 1 -pady 1 @@ -567,7 +710,7 @@ proc startup_cursor {} { global cur_already cur_mode cur_0 cur_1 last_ht global glyphsdone unk_l unk_r - set cur_already [expr {[llength $glyphsdone]/4-1}] + set cur_already [expr {[llength $glyphsdone]/5-1}] set cur_mode 1 ;# one of: 0 1 already text set cur_0 $unk_l @@ -578,13 +721,47 @@ proc startup_cursor {} { #---------- character set runtime display and keystroke handling ---------- +proc char_exactly_selctxts {contexts} { + global all_contexts + foreach ctx [array names all_contexts] { + set ci $all_contexts($ctx) + set selw .d.selctx.c$ci + if {[lsearch -exact $contexts $ctx]>=0} { + set state normal + } else { + set state disabled + } + $selw configure -state $state + } +} + proc recursor/0 {} { recursor//01 0 } proc recursor/1 {} { recursor//01 1 } proc recursor//01 {z1} { - global mul rhsmost_max cols glyphsdone + global mul rhsmost_max cols glyphsdone cur_0 cur_1 + global all_contexts upvar #0 cur_$z1 cur - .d.csr.csr.l configure -text {adjust} + .d.csr.csr.l configure -text "adjust [char_get_definition_context_actual]" place .d.csr.csr -x [expr {$cur*$mul - 7}] + + set okctxts [char_get_definition_contexts] + char_exactly_selctxts $okctxts + + foreach ctx [lsort [array names all_contexts]] { + set key [string range $ctx 0 0] + if {[lsearch -exact $okctxts $ctx] >= 0} { + bind_key [string tolower $key] " + [list set new_context $ctx] + recursor + " + } else { + bind_key [string tolower $key] {} + } + lappend context_help $key + } + set context_help [list [join $context_help " "] \ + {Set match context for new glyph.}] + bind_key space { othercursor } bind_leftright_q cur_$z1 0 [expr {$cols-1}] if {[llength $glyphsdone]} { @@ -593,19 +770,16 @@ proc recursor//01 {z1} { bind_key BackSpace {} } bind_key Return { - if {$cur_0 != $cur_1} { - .d.csr.csr.e delete 0 end - set cur_mode text - recursor - } - } - helptext { - {{<- ->} {move cursor, adjusting area to define}} - {Space {switch to moving other cursor}} - {Return {confirm location, enter letter(s)}} - {Backspace {switch to correcting earlier ocr}} - {Q {quit and abandon OCR run}} + char_start_define_text } + helptext [list \ + {{<- ->} {move cursor, adjusting area to define}} \ + {Space {switch to moving other cursor}} \ + {Return {confirm location, enter letter(s)}} \ + {Backspace {switch to correcting earlier ocr}} \ + {Q {quit and abandon OCR run}} \ + $context_help \ + ] } proc othercursor {} { global cur_mode @@ -613,44 +787,59 @@ proc othercursor {} { recursor } +proc char_start_define_text {} { + global cur_0 cur_1 cur_mode + if {$cur_0 == $cur_1} return + set cdgdca [char_get_definition_context_actual] + if {![string length $cdgdca]} return + .d.csr.csr.e delete 0 end + set cur_mode text + .d.csr.csr.l configure -text "define $cdgdca:" + recursor +} + proc recursor/text {} { + global all_contexts + helptext { {Return {confirm entry of new glyph}} {Escape {abandon entry}} } unbind_all_keys - .d.csr.csr.l configure -text {define:} pack .d.csr.csr.e -side left focus .d.csr.csr.e - bind_key Return { + bind .d.csr.csr.e { set strq [.d.csr.csr.e get] - if {[regexp -line {^(?:[!-[]|[]-~]|\\\\|\\x[0-9a-f]{2})+} $strq]} { - RETURN_RESULT DEFINE "$cur_0 $cur_1 $strq" + if {[string length $strq]} { + RETURN_RESULT DEFINE [list $strq] } } - bind_key Escape { + bind .d.csr.csr.e { bind_key Escape {} pack forget .d.csr.csr.e set cur_mode 1 + focus .d recursor } } proc recursor/already {} { global mul - global glyphsdone global cur_already mul global glyphsdone cur_already mul + + char_exactly_selctxts [lindex $glyphsdone [expr {$cur_already*5+2}]] + .d.csr.csr.l configure -text {correct} - set rmax [lindex $glyphsdone [expr {$cur_already*4}]] + set rmax [lindex $glyphsdone [expr {$cur_already*5}]] place .d.csr.csr -x [expr {$rmax*$mul-3}] bind_key Return {} - bind_leftright_q cur_already 0 [expr {[llength $glyphsdone]/4-1}] + bind_leftright_q cur_already 0 [expr {[llength $glyphsdone]/5-1}] bind_key space { bind_key Delete {}; set cur_mode 1; recursor } bind_key Delete { RETURN_RESULT DELETE [lrange $glyphsdone \ - [expr $cur_already*4] \ - [expr $cur_already*4+2]] + [expr $cur_already*5] \ + [expr $cur_already*5+2]] } helptext { {{<- ->} {move cursor, selecting glyph to correct}} @@ -700,7 +889,8 @@ set database_magic/char {# ypp-sc-tools pctb font v1} proc read_database_header/char {f} { global rows - if {([db_getsl $f])+0 != $rows} { error "wrong h ?" } + set l [db_getsl $f] + if {$l+0 != $rows} { error "wrong h $l $rows ?" } } proc read_database_entry/char {f context} { global database @@ -734,56 +924,91 @@ proc dbkey {ctx l r} { return $bm } -proc update_database/DEFINE {c0 c1 strq} { +proc char_get_definition_cursors {} { + global cur_0 cur_1 + if {$cur_0 <= $cur_1} { + set cl $cur_0; set cr $cur_1 + } else { + set cl $cur_1; set cr $cur_0 + } + incr cr -1 + debug "CGD CURSORS $cl $cr" + return [list $cl $cr] +} + +proc char_get_definition_contexts {} { global glyphsdone unk_l unk_contexts wordmap database - if {$c0 > $c1} { manyset [list $c0 $c1] c1 c0 } + + manyset [char_get_definition_cursors] c0 c1 + if {$c0 == $unk_l} { set ncontexts $unk_contexts } else { - foreach {l r contexts got} $glyphsdone { + foreach {l r context contexts got} $glyphsdone { if {$l==$c0} { set ncontexts $contexts; break } } if {![info exists ncontexts]} { - puts stderr "must start at letter LHS!" - return + set ncontexts {} } } - incr c1 -1 - foreach c $ncontexts { - set bm [dbkey $c $c0 $c1] - set database($bm) $strq + debug "CGD CONTEXTS $ncontexts" + return $ncontexts +} + +proc char_get_definition_context_actual {} { + global new_context + set ncontexts [char_get_definition_contexts] + if {[llength $ncontexts]==1} { + set c [lindex $ncontexts 0] + } elseif {[lsearch -exact $ncontexts $new_context]>=0} { + set c $new_context + } else { + set c {} } - write_database + debug "CDG CONTEXT ACTUAL $c FROM NEW $new_context ALLOW $ncontexts" + return $c +} + +proc update_database/DEFINE {strq} { + manyset [char_get_definition_cursors] c0 c1 + set c [char_get_definition_context_actual] + if {![string length $c]} { + error "Selected context is not one of the many possibilities." + } + debug "DEFINE $strq" + set bm [dbkey $c $c0 $c1] + do_database_update $bm $strq } proc update_database/DELETE {l r ctxs} { global database + if {[llength $ctxs]!=1} { error "$ctxs ?" } foreach ctx $ctxs { set bm [dbkey $ctx $l $r] catch { unset database($bm) } } write_database } - + proc RETURN_RESULT {how what} { - global mainkind + return_result_start + place forget .d.csr.csr pack forget .d.csr.csr.e - helptext {{{ Processing }}} - unbind_all_keys - update idletasks + debug "$how $what" eval update_database/$how $what - done/$mainkind + + return_result_finish } #========== server for approving updates ========== -proc remote-serv-log {dict pirate file event} { +proc remote-serv-log {dict pirate caller file event} { global remoteserv_logf set t [clock format [clock seconds] -format {%Y-%m-%d %H:%M:%S %Z}] - set s [format "%s %-6s %-31s %s %s\n" \ - $t $dict $pirate [file tail $file] $event] + set s [format "%s %-6s %-31s %-31s %s %s\n" \ + $t $dict $pirate $caller [file tail $file] $event] puts -nonewline $remoteserv_logf $s } @@ -805,19 +1030,13 @@ proc remote-serv/take {yesno file dict} { set rows "" debug "TAKE [list $yesno $file $dict]" read_counted stdin pirate + read_counted stdin caller read_counted stdin key read_counted stdin val must_gets_exactly stdin confirmed - if {![string compare pixmap $dict]} { - set reqkind pixmap - debug "DICT PIXMAP" - } elseif {[regexp {^(char)([1-9]\d*)$} $dict dummy reqkind rows]} { - debug "DICT CHAR rqk=$reqkind r=$rows." - } else { - error "$dict ?" - } + manyset [dict2_reqkind_rows $dict] reqkind rows if {$yesno} { read_database $dictdir/master-$dict.txt @@ -827,7 +1046,7 @@ proc remote-serv/take {yesno file dict} { } else { set desc reject } - remote-serv-log $dict $pirate $file "$desc $reqkind $rows" + remote-serv-log $dict $pirate $caller $file "$desc $reqkind $rows" file delete -force $file puts done @@ -878,6 +1097,18 @@ proc regsub-data {exp subspec args} { } } +proc dict2_reqkind_rows {dict} { + if {![string compare pixmap $dict]} { + return {pixmap {}} + debug "DICT PIXMAP" + } elseif {[regexp {^(char)([1-9]\d*)$} $dict dummy reqkind rows]} { + debug "DICT CHAR rqk=$reqkind r=$rows." + return [list $reqkind $rows] + } else { + error "$dict ?" + } +} + proc chop_counted {var} { upvar 1 $var val global data @@ -895,6 +1126,7 @@ proc approve_decompose_data {specdata} { regsub-data {^ypp-sc-tools dictionary update v1\n} {} uplevel 1 chop_counted pirate + uplevel 1 chop_counted caller uplevel 1 chop_counted dict uplevel 1 chop_counted ctx uplevel 1 chop_counted def @@ -911,8 +1143,18 @@ proc approve_compare {fd1 fd2} { return [string compare $sv1 $sv2] } +proc string2unicodenames {str} { + return [exec perl -e { + use Unicode::CharName qw(uname); + $ARGV[0] =~ s/^ //; + foreach $_ (split //,$ARGV[0]) { + print uname(ord),"\n" or die $! + } + } " $str"] +} + proc approve_showentry {ix file specdata} { - global approve_ixes + global approve_ixes reqkind approve_entryhow approve_decompose_data $specdata @@ -936,11 +1178,24 @@ proc approve_showentry {ix file specdata} { image create photo approve/$ix -data $ppm label $wb-image -image approve/$ix -bd 2 -relief sunken - frame $wb-act - button $wb-act.rej -text Reject -command [list approve_reject $ix] - pack $wb-act.rej + manyset [dict2_reqkind_rows $dict] reqkind + approve_showentry_xinfo/$reqkind $wb-xinfo $def + + if {$ix} { + label $wb-div -bd 1 -relief sunken -image image/empty + grid configure $wb-div -columnspan 5 -sticky ew -padx 5 + } + + frame $wb-act -bd 2 -relief groove + set approve_entryhow($ix) approve + foreach how {approve reject defer} { + set w $wb-act.$how + radiobutton $w -variable approve_entryhow($ix) \ + -text [string totitle $how] -value $how + pack $w -side left + } - grid $wb-def $wb-image $wb-act $wb-inf -padx 3 + grid $wb-def $wb-image $wb-xinfo $wb-act $wb-inf -padx 3 grid configure $wb-image -ipadx 3 -ipady 3 -sticky w lappend approve_ixes $ix @@ -952,6 +1207,7 @@ proc approve_approve_reject_one {ix yesno} { approve_decompose_data $tdata puts_server "take $yesno $file $dict" puts_counted $server pirate + puts_counted $server caller puts_counted $server key puts_counted $server val puts_server confirmed @@ -966,16 +1222,18 @@ proc approve_check_server {} { must_gets_exactly_server ok } -proc approve_reject {ix} { +proc approve_confirm {} { + global approve_ixes approve_entryhow approve_check_server - approve_approve_reject_one $ix 0 - approve_fetch_list -} - -proc approve_these {} { - global approve_ixes - approve_check_server - foreach ix $approve_ixes { approve_approve_reject_one $ix 1 } + foreach ix $approve_ixes { + set how $approve_entryhow($ix) + switch -exact $how { + approve { approve_approve_reject_one $ix 1 } + reject { approve_approve_reject_one $ix 0 } + defer { } + default { error $how? } + } + } approve_fetch_list } @@ -1008,14 +1266,18 @@ proc main/approve {} { if {[llength $argv] != 3} { error "wrong # args" } manyset $argv userhost directory dictdir + debug "APPROVER FOR $userhost $directory $dictdir" + set cmd [list tclsh $directory/dictionary-manager] if {$debug} { lappend cmd --debug-server } lappend cmd --remote-server-1 $directory $dictdir switch -glob $userhost { {} { } {* *} { set cmd $userhost } - * { set cmd [append [list ssh $userhost] $cmd] } + * { set cmd [concat [list ssh -o compression=yes $userhost] $cmd] } } + debug "APPROVER RUNS $cmd" + lappend cmd 2>@ stderr set server [open |$cmd r+] must_gets_exactly_server $remoteserv_banner @@ -1025,12 +1287,14 @@ proc main/approve {} { label .title -text {} frame .app -bd 2 -relief groove - button .ok -text "Approve These" -command approve_these + button .ok -text "Confirm" -command approve_confirm pack .title .app -side top pack .left -side left pack .right -side right pack .ok -side bottom + image create bitmap image/empty + set approve_page 0 approve_fetch_list } @@ -1067,6 +1331,16 @@ proc approve_show_page {delta} { #========== main program ========== +proc return_result_start {} { + helptext {{{ Processing }}} + unbind_all_keys + update idletasks +} +proc return_result_finish {} { + global mainkind + done/$mainkind +} + proc main/default {} { puts stderr "Do not run this program directly." exit 12 @@ -1103,9 +1377,11 @@ proc debug {m} { } set mainkind default set ai 0 set debug 0 +set quiet 0 foreach arg $argv { incr ai switch -exact -- $arg { + {--quiet} { set quiet 1 } {--debug} { set debug 1 } {--debug-server} { proc debug {m} { puts stderr "DICT-MGR-SVR $m" }} {--noop-arg} { }