1#!/bin/sh
2# --- tcl/tk-GUI for gocr --- (c) Joerg Schulenburg
3#  start: wish gocr.tcl
4#
5#  tested on: tk8.0 (linux,win95)
6#
7# ToDo:
8#  - better using wishx with extended Tcl? (for pipe etc.)
9#  - Reading from stderr of child???
10#
11# this is a multiline comment in wish, but not in sh \
12exec /usr/local/bin/wish8.6 -f $0 $@
13
14set ver 0.3.6
15set gocrver 0.3.5
16
17# v0.3.6
18#  - adaption to gocr v0.3, new options
19# ToDo:
20#  - xviewer as option (xli), proc view { image } { handle it }
21#    image gif ppm pgm (use xli -geometry WxH[{+-}X{+-}Y] out30.bmp #!)
22#  - output file as option, colored text (bad chars red)
23#  - last/current command on status line (at bottom)
24#  - capture error channel from gocr seperately
25#  - use -f inifile as option
26#
27# Thanks to famous tk/tcl developper! Realy good language for x11 beginner.
28#
29wm title . "GOCR Tcl frontend $ver"
30
31set spacewidth 0
32set graylevel 160
33set dustsize 20
34set imgviewer "xli -geometry 400x400 "
35set gocrpath "gocr"
36set gocraddopt "-e - -f UTF8"
37set file "../examples/text.pbm"
38set ofile "out01.txt"
39# entry out{n+1}.txt can automaticly generated!
40if  $argc {
41 puts " ignore $argc arguments: $argv"
42}
43
44frame .mbar -borderwidth 1 -relief raised
45pack .mbar -fill x
46
47menubutton .mbar.file -text "File" -menu .mbar.file.m
48pack .mbar.file -side left
49menu .mbar.file.m
50# .mbar.file.m add command -label "create font1.pbm" -command exit
51.mbar.file.m add command -label "Clear output" -command {$log delete 0.0 end}
52.mbar.file.m add command -label "Save output" -command {ofileDialog .mbar.file.m; SaveText $ofile}
53.mbar.file.m add command -label "Exit" -command exit
54
55
56menubutton .mbar.options -text "Options" -menu .mbar.options.m
57pack .mbar.options -side left
58menu .mbar.options.m
59.mbar.options.m add command -label "set Options" -command Option
60.mbar.options.m add command -label "Save options" -command SaveOpt
61.mbar.options.m add command -label "Load options" -command LoadOpt
62set m1 0
63set m2 0
64set m3 0
65set m4 0
66set m5 0
67set m6 0
68set v0 0
69set v1 0
70set v2 0
71set v3 0
72set v4 0
73set v5 0
74# set for automatic detection
75set autos 1
76set autol 1
77set autod 1
78
79
80menubutton .mbar.help -text "Help" -menu .mbar.help.m
81pack .mbar.help -side right
82menu .mbar.help.m
83.mbar.help.m add command -label "About" -command aboutBox
84# .mbar.help.m add command -label "Version"
85
86# --------------------- action frame -----------------------
87frame .abar -borderwidth 1 -relief sunken
88pack .abar -fill x
89
90set but [button .abar.go -text "Run it" -command Run]
91#button .abar.go -text "Run it" -command { Run }
92pack .abar.go -side left
93
94set f .abar
95set w .abar
96label .abar.labf -text "File:"
97button .abar.file -text "Browse" -command "fileDialog $w $f.entf open"
98button .abar.show -text "Show" -command "Show"
99button .abar.spell -text "Spell" -command "Spell"
100button .abar.scan -text "Scan" -command "Scan"
101entry .abar.entf -width 40
102pack .abar.labf -side left
103pack .abar.entf -side left
104pack .abar.file -side left
105pack .abar.show -side left
106pack .abar.spell -side left
107pack .abar.scan -side left
108.abar.entf insert 0 $file
109
110label .abar.status -text "ready"
111pack .abar.status -side right
112
113# ------------------ canvas, text ? -----------------
114#canvas .pad -background white
115#pack .pad
116
117frame .t
118#text .t
119#pack .t
120##.t insert end "history:"
121##.t configure -state disabled
122
123
124set log [text .t.log -width 80 -height 30 \
125  -borderwidth 2 -relief raised -setgrid true\
126  -yscrollcommand {.t.scroll set}]
127scrollbar .t.scroll -command {.t.log yview}
128pack .t.scroll -side right -fill y
129pack .t.log -side left -fill both -expand true
130# pack .t -side top -fill both -expand true
131#####################################################
132
133frame .tmsg
134set log2 [text .tmsg.log -width 80 -height 5 \
135  -borderwidth 2 -relief raised -setgrid true\
136  -yscrollcommand {.tmsg.scroll set}]
137scrollbar .tmsg.scroll -command {.tmsg.log yview}
138pack .tmsg.scroll -side right -fill y
139pack .tmsg.log -side left -fill both -expand true
140pack .t .tmsg -side top -fill both -expand true
141#####################################################
142
143bind .abar.entf <Return> Run
144bind .abar.entf <Control-c> Stop
145focus .abar.entf
146
147
148$log2 insert end "\n   ! ! !  This program is in development.  Use carefully ! ! !\n\n"
149
150# tk_messageBox -icon info -type ok -title "Info" -message \
151#  "This program is in development!\nUse carefully!\n"
152
153
154# --------------------- File ---------------------
155# see /usr/lib/tk8.0/demos/filebox.tcl
156proc fileDialog {w ent operation} {
157    #   Type names		Extension(s)	Mac File Type(s)
158    #
159    #---------------------------------------------------------
160    set types {
161        {"PNM files"		{.pnm .pbm .pgm .ppm}	}
162        {"Image Files"		{.tga .pcx}		}
163        {"Image Files"		{.gif .bmp .tiff .png}	}
164        {"Image Files"		{.jpeg .jpg}		}
165        {"Image Files"		""		{GIFF JPEG}}
166        {"All files"		*}
167    }
168    if {$operation == "open"} {
169      set file [tk_getOpenFile -filetypes $types -parent $w]
170    } else {
171      set file [tk_getSaveFile -filetypes $types -parent $w \
172        -initialfile Untitled -defaultextension .txt]
173    }
174    if [string compare $file ""] {
175        $ent delete 0 end
176        $ent insert 0 $file
177        $ent xview end
178    }
179}
180
181# --------------------- oFile ---------------------
182# see /usr/lib/tk8.0/demos/filebox.tcl
183proc ofileDialog {w} {
184    global ofile
185    #   Type names		Extension(s)
186    set types {
187        {"text files"		{.txt .text .asc}	}
188        {"HTML files"		{.html .htm}		}
189        {"All files"		*}
190    }
191    set ofile [tk_getSaveFile -filetypes $types -parent $w \
192        -initialfile $ofile -defaultextension .txt]
193    update
194}
195
196# --------------------- Show Picture ---------------------
197proc Show {} {
198  global file, imgviewer
199  set file [.abar.entf get]
200  eval exec $imgviewer $file &
201}
202
203# --------------------- Spell check ---------------------
204proc Spell {} {
205  global ofile
206# WARNING: this clobbers out.txt (fixme)
207  SaveText $ofile
208  exec tkispell $ofile &
209}
210
211# --------------------- Scan ---------------------
212proc Scan {} {
213  exec xsane -s -n &
214}
215
216# --------------------- Options ---------------------
217proc SaveOpt {} {
218  global v0 v1 v2 v3 v4 v5 m1 m2 m3 m4 m5 m6 spacewidth graylevel dustsize imgviewer ofile
219  global autos autod autol gocrpath gocraddopt
220  if [catch {open .gocr w} out] {
221    puts "open .gocr failed"
222    return
223  }
224  set file [.abar.entf get]
225  set vvv  [expr $v0 + $v1 + $v2 + $v3 + $v4 + $v5 ]
226  set mode [expr $m1 + $m2 + $m3 + $m4 + $m5 + $m6 ]
227  puts $out "vvv $vvv"
228  puts $out "mode $mode"
229  puts $out "file $file"
230  puts $out "ofile $ofile"
231  puts $out "spacewidth $spacewidth"
232  puts $out "graylevel $graylevel"
233  puts $out "dustsize $dustsize"
234  puts $out "imgviewer $imgviewer"
235  puts $out "autos $autos"
236  puts $out "autod $autod"
237  puts $out "autol $autol"
238  puts $out "gocrpath $gocrpath"
239  puts $out "gocraddopt $gocraddopt"
240  close $out
241}
242
243proc LoadOpt {} {
244  global v0 v1 v2 v3 v4 v5 m1 m2 m3 m4 m5 m6 spacewidth graylevel dustsize imgviewer ofile
245  global autos autod autol gocrpath gocraddopt
246  set file [.abar.entf get]
247  set vvv  [expr $v0 + $v1 + $v2 + $v3 + $v4 + $v5 ]
248  set mode [expr $m1 + $m2 + $m3 + $m4 + $m5 + $m6 ]
249  if [catch {open .gocr r} in] {
250    puts "open .gocr failed"
251    return
252  }
253  while {[ gets $in line] >=0} {
254    if { [string first "vvv"   "$line"] == 0 } { scan $line "%s%d" buf vvv }
255    if { [string first "mode"  "$line"] == 0 } { scan $line "%s%d" buf mode }
256    if { [string first "file"  "$line"] == 0 } { scan $line "%s%s" buf file }
257    if { [string first "ofile" "$line"] == 0 } { scan $line "%s%s" buf ofile }
258    if { [string first "gray"  "$line"] == 0 } { scan $line "%s%d" buf graylevel }
259    if { [string first "dust"  "$line"] == 0 } { scan $line "%s%d" buf dustsize }
260    if { [string first "imgv"  "$line"] == 0 } { scan $line "%s%d" buf imgviewer }
261    if { [string first "autos" "$line"] == 0 } { scan $line "%s%d" buf autos }
262    if { [string first "autod" "$line"] == 0 } { scan $line "%s%d" buf autod }
263    if { [string first "autol" "$line"] == 0 } { scan $line "%s%d" buf autol }
264    if { [string first "gocrpath" "$line"] == 0 } { scan $line "%s%s" buf gocrpath }
265    if { [string first "gocraddopt" "$line"] == 0 } { set gocraddopt [ string range "$line" 11 256 ] }
266  }
267  close $in
268  .abar.entf delete 0 end
269  .abar.entf insert 0 $file
270  .abar.entf xview end
271  set v0  [expr $vvv & 1 ]
272  set v1  [expr $vvv & 2 ]
273  set v2  [expr $vvv & 4 ]
274  set v3  [expr $vvv & 8 ]
275  set v4  [expr $vvv & 16 ]
276  set v5  [expr $vvv & 32 ]
277  set m6  [expr $mode & 64 ]
278  set m1  [expr $mode & 2 ]
279  set m2  [expr $mode & 4 ]
280  set m3  [expr $mode & 8 ]
281  set m4  [expr $mode & 16 ]
282  set m5  [expr $mode & 32 ]
283}
284
285# call it once
286LoadOpt
287
288# see /usr/lib/tk8.0/demos/check.tcl
289proc Option {} {
290  global v0 v1 v2 v3 v4 m1 m2 m3 m4 m5 m6 spacewidth graylevel dustsize imgviewer
291  global autos autod autol gocrpath gocraddopt
292  set w .woption
293  catch {destroy $w}
294  toplevel $w
295  wm title $w "GOCR Options"
296
297
298set ww $w
299
300
301 label $ww.msg -wraplength 4i -justify left -text "Here you can set several options for GOCR."
302 pack $ww.msg -side top
303
304 frame $w.buttons
305 pack $w.buttons -side bottom -fill x -pady 2m
306 button $w.buttons.ok   -text "Ok" -command "destroy $w"
307 button $w.buttons.vars -text "See Variables" -command "showVars"
308 pack $w.buttons.vars $w.buttons.ok -side left -expand 1
309
310 frame $ww.sep1 -relief ridge -bd 1 -height 2
311 pack $ww.sep1 -side top -fill x
312#  -expand no
313
314 frame $ww.scale1
315 pack $ww.scale1 -side top -fill x
316 label $ww.scale1.label -text "spacewidth:" -width 16
317 scale $ww.scale1.scale -orient horizontal -length 200 -from 0 -to 60 \
318        -variable spacewidth
319 checkbutton $ww.scale1.check -text "auto" -variable autos -onvalue  1 -offvalue  0
320 pack $ww.scale1.label $ww.scale1.scale $ww.scale1.check -side left
321
322 frame $ww.scale2
323 pack $ww.scale2 -side top -fill x
324 label $ww.scale2.label -text "graylevel:" -width 16
325 scale $ww.scale2.scale -orient horizontal -length 200 -from 0 -to 255 \
326        -variable graylevel
327 checkbutton $ww.scale2.check -text "auto" -variable autol -onvalue  1 -offvalue  0
328 pack $ww.scale2.label $ww.scale2.scale $ww.scale2.check -side left
329
330 frame $ww.scale3
331 pack $ww.scale3 -side top -fill x
332 label $ww.scale3.label -text "dustsize:" -width 16
333 scale $ww.scale3.scale -orient horizontal -length 200 -from 0 -to 60 \
334        -variable dustsize
335 checkbutton $ww.scale3.check -text "auto" -variable autod -onvalue  1 -offvalue  0
336 pack $ww.scale3.label $ww.scale3.scale $ww.scale3.check -side left
337
338 frame $ww.sep2 -relief ridge -bd 1 -height 2
339 pack $ww.sep2 -side top -fill x
340#  -expand no
341
342 # place the checkbuttons in two columns
343 frame $ww.cb
344 pack $ww.cb -side top -fill x
345 frame $ww.cb.cb1 -relief ridge -bd 1 -height 2
346 pack $ww.cb.cb1 -side left -fill y
347 frame $ww.cb.sep3 -relief ridge -bd 1 -height 2
348 pack $ww.cb.sep3 -side left -fill y
349 frame $ww.cb.cb2 -relief ridge -bd 1 -height 2
350 pack $ww.cb.cb2 -side left -fill y
351
352set ww $w.cb.cb1
353
354 label $ww.msg1 -text "Mode options (work mode):"
355 pack $ww.msg1 -side top
356 checkbutton $ww.b1 -text "use database"       -variable m1 -onvalue  2 -offvalue  0
357 checkbutton $ww.b2 -text "layout analysis"    -variable m2 -onvalue  4 -offvalue  0
358 checkbutton $ww.b3 -text "compare _ mode"     -variable m3 -onvalue  0 -offvalue  8
359 checkbutton $ww.b4 -text "divide  _ mode"     -variable m4 -onvalue  0 -offvalue 16
360 checkbutton $ww.b5 -text "context correction" -variable m5 -onvalue  0 -offvalue 32
361 checkbutton $ww.b6 -text "char packing"       -variable m6 -onvalue 64 -offvalue  0
362 pack $ww.b1 $ww.b2 $ww.b3 $ww.b4 $ww.b5 $ww.b6 -side top -pady 2 -anchor w
363
364
365set ww $w.cb.cb2
366
367 label $ww.msg2 -text "Verbose options (output mode):"
368 pack $ww.msg2 -side top
369 checkbutton $ww.c1 -text "more info"        -variable v0 -onvalue  1 -offvalue 0
370 checkbutton $ww.c2 -text "list chapes"      -variable v1 -onvalue  2 -offvalue 0
371 checkbutton $ww.c3 -text "list pattern"     -variable v2 -onvalue  4 -offvalue 0
372 checkbutton $ww.c4 -text "list all pattern" -variable v3 -onvalue  8 -offvalue 0
373 checkbutton $ww.c5 -text "line infos"       -variable v4 -onvalue 16 -offvalue 0
374 checkbutton $ww.c6 -text "debug mode"       -variable v5 -onvalue 32 -offvalue 0
375 pack $ww.c1 $ww.c2 $ww.c3 $ww.c4 $ww.c5 $ww.c6 -side top -pady 2 -anchor w
376
377set ww $w
378
379 frame $ww.sep4 -relief ridge -bd 1 -height 2
380 pack $ww.sep4 -side top -fill x
381
382set ww $w.l1
383 frame $ww
384 pack $ww -side top -fill x
385
386 label $ww.d1 -text "Image Viewer:" -width 16
387 entry $ww.d2 -textvariable imgviewer
388 pack $ww.d1 -side left -pady 2 -padx 2 -anchor w
389 pack $ww.d2 -side left -pady 2 -padx 2 -fill x -expand 1 -anchor w
390
391set ww $w.l2
392 frame $ww
393 pack $ww -side top -fill x
394
395 label $ww.e1 -text "GOCR PATH:" -width 16
396 entry $ww.e2 -textvariable gocrpath
397 pack $ww.e1 -side left -pady 2 -padx 2 -anchor w
398 pack $ww.e2 -side left -pady 2 -padx 2 -fill x -expand 1 -anchor w
399
400set ww $w.l3
401 frame $ww
402 pack $ww -side top -fill x
403
404 label $ww.f1 -text "add OPTIONS:" -width 16
405 entry $ww.f2 -textvariable gocraddopt
406 pack $ww.f1 -side left -pady 2 -padx 2 -anchor w
407 pack $ww.f2 -side left -pady 2 -padx 2 -fill x -expand 1 -anchor w
408
409
410}
411
412# ----------------------------- showVars -----------------------------
413proc showVars {} {
414  global fid but log2 file v0 v1 v2 v3 v4 v5 m1 m2 m3 m4 m5 m6 spacewidth graylevel dustsize imgviewer
415  global autos autod autol gocrpath gocraddopt
416  set file [.abar.entf get]
417  set vvv  [expr $v0 + $v1 + $v2 + $v3 + $v4 + $v5 ]
418  set mode [expr $m1 + $m2 + $m3 + $m4 + $m5 + $m6 ]
419  set run "$gocrpath -v $vvv -m $mode"
420  if [ expr $autos == 0 ] { set run "$run -s $spacewidth" }
421  if [ expr $autol == 0 ] { set run "$run -l $graylevel" }
422  if [ expr $autod == 0 ] { set run "$run -d $dustsize" }
423  set run "$run $gocraddopt $file"
424  $log2 insert end "run = $run\n"
425  update
426}
427
428
429# ----------------------------- saveLog -----------------------------
430proc SaveText { txtfile } {
431  global log
432  if [catch {open $txtfile w} out] {
433    puts "open $txtfile failed"
434    return
435  }
436  puts $out [$log get 0.0 end]
437  close $out
438}
439
440
441# ----------------------------- RUN -----------------------------
442proc Run {} {
443  global fid but log log2 file v0 v1 v2 v3 v4 v5 m1 m2 m3 m4 m5 m6 spacewidth graylevel dustsize imgviewer
444  global autos autod autol gocrpath gocraddopt
445  set file [.abar.entf get]
446  set pin ""
447  if [ string match *.p?m.gz $file ] {
448    set pin "gzip -cd $file |"
449    set file -
450  } elseif [ string match *.gif $file ] {
451    set pin "giftopnm $file |"
452    set file -
453  } elseif { [ string match *.tif $file ] || [ string match *.tiff $file ] } {
454    set pin "tifftopnm $file |"
455    set file -
456  } elseif { [ string match *.bmp $file ] } {
457    set pin "bmptopnm $file |"
458    set file -
459  } elseif { [ string match *.png $file ] } {
460    set pin "pngtopnm $file |"
461    set file -
462  } elseif { [ string match *.jpg $file ] || [ string match *.jpeg $file ] } {
463    set pin "djpeg -gray -pnm $file |"
464    set file -
465  }
466  set vvv  [expr $v0 + $v1 + $v2 + $v3 + $v4 + $v5 ]
467  set mode [expr $m1 + $m2 + $m3 + $m4 + $m5 + $m6 ]
468  set run "$pin $gocrpath -v $vvv -m $mode"
469  if [ expr $autos == 0 ] { set run "$run -s $spacewidth" }
470  if [ expr $autol == 0 ] { set run "$run -l $graylevel" }
471  if [ expr $autod == 0 ] { set run "$run -d $dustsize" }
472  set run "$run $gocraddopt $file"
473  $log2 insert end $run\n
474  $log2 see end
475  if [catch {open "| $run" } fid] {
476    $log2 insert end $fid\n
477  } else {
478    # puts "listening on $fid (file4)"
479    fileevent $fid readable Log
480    # How to read from stderr of child???
481    .abar.status configure -text "progress"
482    update
483#    $log insert end $run\n
484    $but config -text "Stop !" -command Stop
485  }
486## gets $fid ; # ead headerline
487#  fileevent $fid readable "get_samples $fid"
488}
489
490proc Log {} {
491  global fid log
492  if [eof $fid] { Stop } else {
493    gets $fid line
494    $log insert end $line\n
495    $log see end
496  }
497}
498
499proc Log2 {} {
500  global log2 fid2
501  # read from stderr-child???
502  if [eof $fid2] { Stop } else {
503    gets $fid2 line
504    $log2 insert end $line\n
505    $log2 see end
506  }
507}
508
509proc Stop {} {
510  global fid but v5
511  catch {close $fid}
512  $but config -text "Run it" -command Run
513  .abar.status configure -text "ready"
514  update
515}
516
517
518# aboutBox --
519#
520#       Pops up a message box with an "about" message
521#
522proc aboutBox {} {
523  global ver gocrver
524     tk_messageBox -icon info -type ok -title "About" -message \
525    "Tcl/Tk front end\nto GOCR $gocrver\n\nversion $ver (c) 2002 Joerg Schulenburg"
526}
527
528