Subversion Repositories Vertical

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
# A Notebook widget for Tcl/Tk
2
# $Revision: 1.1.1.1 $
3
#
4
# Copyright (C) 1996,1997,1998 D. Richard Hipp
5
#
6
# This library is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU Library General Public
8
# License as published by the Free Software Foundation; either
9
# version 2 of the License, or (at your option) any later version.
10
#
11
# This library is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# Library General Public License for more details.
15
# 
16
# You should have received a copy of the GNU Library General Public
17
# License along with this library; if not, write to the
18
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
# Boston, MA  02111-1307, USA.
20
#
21
# Author contact information:
22
#   drh@acm.org
23
#   http://www.hwaci.com/drh/
24
 
25
#
26
# Create a new notebook widget
27
#
28
proc Notebook:create {w args} {
29
  global Notebook
30
  set Notebook($w,width) 400
31
  set Notebook($w,height) 300
32
  set Notebook($w,pages) {}
33
  set Notebook($w,top) 0
34
  set Notebook($w,pad) 5
35
  set Notebook($w,fg,on) black
36
  set Notebook($w,fg,off) grey50
37
  canvas $w -bd 0 -highlightthickness 0 -takefocus 0
38
  set Notebook($w,bg) [$w cget -bg]
39
  bind $w <1> "Notebook:click $w %x %y"
40
  bind $w <Configure> "Notebook:scheduleExpand $w"
41
  eval Notebook:config $w $args
42
}
43
 
44
#
45
# Change configuration options for the notebook widget
46
#
47
proc Notebook:config {w args} {
48
  global Notebook
49
  foreach {tag value} $args {
50
    switch -- $tag {
51
      -width {
52
        set Notebook($w,width) $value
53
      }
54
      -height {
55
        set Notebook($w,height) $value
56
      }
57
      -pages {
58
        set Notebook($w,pages) $value
59
      }
60
      -pad {
61
        set Notebook($w,pad) $value
62
      }
63
      -bg {
64
        set Notebook($w,bg) $value
65
      }
66
      -fg {
67
        set Notebook($w,fg,on) $value
68
      }
69
      -disabledforeground {
70
        set Notebook($w,fg,off) $value
71
      }
72
    }
73
  }
74
 
75
  #
76
  # After getting new configuration values, reconstruct the widget
77
  #
78
  $w delete all
79
  set Notebook($w,x1) $Notebook($w,pad)
80
  set Notebook($w,x2) [expr $Notebook($w,x1)+2]
81
  set Notebook($w,x3) [expr $Notebook($w,x2)+$Notebook($w,width)]
82
  set Notebook($w,x4) [expr $Notebook($w,x3)+2]
83
  set Notebook($w,y1) [expr $Notebook($w,pad)+2]
84
  set Notebook($w,y2) [expr $Notebook($w,y1)+2]
85
  set Notebook($w,y5) [expr $Notebook($w,y1)+30]
86
  set Notebook($w,y6) [expr $Notebook($w,y5)+2]
87
  set Notebook($w,y3) [expr $Notebook($w,y6)+$Notebook($w,height)]
88
  set Notebook($w,y4) [expr $Notebook($w,y3)+2]
89
  set x $Notebook($w,x1)
90
  set cnt 0
91
  set y7 [expr $Notebook($w,y1)+10]
92
  label $w.dummy -text hi
93
  set font [$w.dummy cget -font]
94
  destroy $w.dummy
95
  foreach p $Notebook($w,pages) {
96
    set Notebook($w,p$cnt,x5) $x
97
    set id [$w create text 0 0 -text $p -anchor nw \
98
           -font $font -tags "p$cnt t$cnt"]
99
    set bbox [$w bbox $id]
100
    set width [lindex $bbox 2]
101
    $w move $id [expr $x+10] $y7
102
    $w create line \
103
       $x $Notebook($w,y5)\
104
       $x $Notebook($w,y2) \
105
       [expr $x+2] $Notebook($w,y1) \
106
       [expr $x+$width+16] $Notebook($w,y1) \
107
       -width 2 -fill white -tags p$cnt
108
    $w create line \
109
       [expr $x+$width+16] $Notebook($w,y1) \
110
       [expr $x+$width+18] $Notebook($w,y2) \
111
       [expr $x+$width+18] $Notebook($w,y5) \
112
       -width 2 -fill black -tags p$cnt
113
    set x [expr $x+$width+20]
114
    set Notebook($w,p$cnt,x6) [expr $x-2]
115
    if {![winfo exists $w.f$cnt]} {
116
      frame $w.f$cnt -bd 0
117
    }
118
    $w.f$cnt config -bg $Notebook($w,bg)
119
    place $w.f$cnt -x $Notebook($w,x2) -y $Notebook($w,y6) \
120
      -width $Notebook($w,width) -height $Notebook($w,height)
121
    incr cnt
122
  }
123
  $w create line \
124
     $Notebook($w,x1) [expr $Notebook($w,y5)-2] \
125
     $Notebook($w,x1) $Notebook($w,y3) \
126
     -width 2 -fill white
127
  $w create line \
128
     $Notebook($w,x1) $Notebook($w,y3) \
129
     $Notebook($w,x2) $Notebook($w,y4) \
130
     $Notebook($w,x3) $Notebook($w,y4) \
131
     $Notebook($w,x4) $Notebook($w,y3) \
132
     $Notebook($w,x4) $Notebook($w,y6) \
133
     $Notebook($w,x3) $Notebook($w,y5) \
134
     -width 2 -fill black
135
  $w config -width [expr $Notebook($w,x4)+$Notebook($w,pad)] \
136
            -height [expr $Notebook($w,y4)+$Notebook($w,pad)] \
137
            -bg $Notebook($w,bg)
138
  set top $Notebook($w,top)
139
  set Notebook($w,top) -1
140
  Notebook:raise.page $w $top
141
}
142
 
143
#
144
# This routine is called whenever the mouse-button is pressed over
145
# the notebook.  It determines if any page should be raised and raises
146
# that page.
147
#
148
proc Notebook:click {w x y} {
149
  global Notebook
150
  if {$y<$Notebook($w,y1) || $y>$Notebook($w,y6)} return
151
  set N [llength $Notebook($w,pages)]
152
  for {set i 0} {$i<$N} {incr i} {
153
    if {$x>=$Notebook($w,p$i,x5) && $x<=$Notebook($w,p$i,x6)} {
154
      Notebook:raise.page $w $i
155
      break
156
    }
157
  }
158
}
159
 
160
#
161
# For internal use only.  This procedure raised the n-th page of
162
# the notebook
163
#
164
proc Notebook:raise.page {w n} {
165
  global Notebook
166
  if {$n<0 || $n>=[llength $Notebook($w,pages)]} return
167
  set top $Notebook($w,top)
168
  if {$top>=0 && $top<[llength $Notebook($w,pages)]} {
169
    $w move p$top 0 2
170
  }
171
  $w move p$n 0 -2
172
  $w delete topline
173
  if {$n>0} {
174
    $w create line \
175
       $Notebook($w,x1) $Notebook($w,y6) \
176
       $Notebook($w,x2) $Notebook($w,y5) \
177
       $Notebook($w,p$n,x5) $Notebook($w,y5) \
178
       $Notebook($w,p$n,x5) [expr $Notebook($w,y5)-2] \
179
       -width 2 -fill white -tags topline
180
  }
181
  $w create line \
182
    $Notebook($w,p$n,x6) [expr $Notebook($w,y5)-2] \
183
    $Notebook($w,p$n,x6) $Notebook($w,y5) \
184
    -width 2 -fill white -tags topline
185
  $w create line \
186
    $Notebook($w,p$n,x6) $Notebook($w,y5) \
187
    $Notebook($w,x3) $Notebook($w,y5) \
188
    -width 2 -fill white -tags topline
189
  set Notebook($w,top) $n
190
  raise $w.f$n
191
}
192
 
193
#
194
# Change the page-specific configuration options for the notebook
195
#
196
proc Notebook:pageconfig {w name args} {
197
  global Notebook
198
  set i [lsearch $Notebook($w,pages) $name]
199
  if {$i<0} return
200
  foreach {tag value} $args {
201
    switch -- $tag {
202
      -state {
203
        if {"$value"=="disabled"} {
204
          $w itemconfig t$i -fg $Notebook($w,fg,off)
205
        } else {
206
          $w itemconfig t$i -fg $Notebook($w,fg,on)
207
        }
208
      }
209
      -onexit {
210
        set Notebook($w,p$i,onexit) $value
211
      }
212
    }
213
  }
214
}
215
 
216
#
217
# This procedure raises a notebook page given its name.  But first
218
# we check the "onexit" procedure for the current page (if any) and
219
# if it returns false, we don't allow the raise to proceed.
220
#
221
proc Notebook:raise {w name} {
222
  global Notebook
223
  set i [lsearch $Notebook($w,pages) $name]
224
  if {$i<0} return
225
  if {[info exists Notebook($w,p$i,onexit)]} {
226
    set onexit $Notebook($w,p$i,onexit)
227
    if {"$onexit"!="" && [eval uplevel #0 $onexit]!=0} {
228
      Notebook:raise.page $w $i
229
    }
230
  } else {
231
    Notebook:raise.page $w $i
232
  }
233
}
234
 
235
#
236
# Return the frame associated with a given page of the notebook.
237
#
238
proc Notebook:frame {w name} {
239
  global Notebook
240
  set i [lsearch $Notebook($w,pages) $name]
241
  if {$i>=0} {
242
    return $w.f$i
243
  } else {
244
    return {}
245
  }
246
}
247
 
248
#
249
# Try to resize the notebook to the next time we become idle.
250
#
251
proc Notebook:scheduleExpand w {
252
  global Notebook
253
  if {[info exists Notebook($w,expand)]} return
254
  set Notebook($w,expand) 1
255
  after idle "Notebook:expand $w"
256
}
257
 
258
#
259
# Resize the notebook to fit inside its containing widget.
260
#
261
proc Notebook:expand w {
262
  global Notebook
263
  set wi [expr [winfo width $w]-($Notebook($w,pad)*2+4)]
264
  set hi [expr [winfo height $w]-($Notebook($w,pad)*2+36)]
265
  Notebook:config $w -width $wi -height $hi
266
  catch {unset Notebook($w,expand)}
267
}
268
 
269
# End of the notebook widget.
270
#################################
271
 
272
################################ Label Frame #############################
273
#
274
#
275
proc LabelFrame:create {w args} {
276
  frame $w -bd 0
277
  label $w.l
278
  frame $w.f -bd 2 -relief groove
279
  frame $w.f.f
280
  pack $w.f.f
281
  set text {}
282
  set font {}
283
  set padx 3
284
  set pady 7
285
  set ipadx 2
286
  set ipady 9
287
  foreach {tag value} $args {
288
    switch -- $tag {
289
      -font   {set font $value}
290
      -text   {set text $value}
291
      -padx   {set padx $value}
292
      -pady   {set pady $value}
293
      -ipadx  {set ipadx $value}
294
      -ipady  {set ipady $value}
295
      -bd     {$w.f config -bd $value}
296
      -relief {$w.f config -relief $value}
297
    }
298
  }
299
  if {"$font"!=""} {
300
    $w.l config -font $font
301
  }
302
  $w.l config -text $text
303
  pack $w.f -padx $padx -pady $pady -fill both -expand 1
304
  place $w.l -x [expr $padx+10] -y $pady -anchor w
305
  pack $w.f.f -padx $ipadx -pady $ipady -fill both -expand 1
306
  raise $w.l
307
  return $w.f.f
308
}
309
# End of the labeled frame widget.
310
########################################################
311
 
312
#########################################################
313
# Directory Selector TCL version 1.1
314
#
315
# Originally written by:
316
# Daniel Roche, <dan@lectra.com>
317
#
318
# Modified for xmktclapp (and for version of Tk prior to 8.0) by:
319
# D. Richard Hipp, <drh@hwaci.com>
320
 
321
# tk_getDirectory [option value ...]
322
#
323
#  options are :
324
#   [-initialdir dir]     display in dir
325
#   [-title string]       make string title of dialog window
326
#   [-ok string]          make string the label of OK button
327
#   [-open string]        make string the label of OPEN button
328
#   [-cancel string]      make string the label of CANCEL button
329
#   [-msg1 string]        make string the label of the first directory message
330
#   [-msg2 string]        make string the label of the second directory message
331
#
332
proc tk_getDirectory {args} {
333
    global tcl_platform tk_getDirectory
334
 
335
    #
336
    # arguments
337
    #
338
    set _titre "Directory Selector"
339
    set _ldir Directory:
340
    set _ldnam "Directory Name:"
341
    set _open Ok
342
    set _expand Open
343
    set _cancel Cancel
344
    if {![info exists tk_getDirectory(curdir)]} {
345
      set tk_getDirectory(curdir) [pwd]
346
    }
347
 
348
    set ind 0
349
    set max [llength $args]
350
    while { $ind < $max } {
351
        switch -exact -- [lindex $args $ind] {
352
            "-initialdir" {
353
                incr ind
354
                set tk_getDirectory(curdir) [lindex $args $ind]
355
                incr ind
356
            }
357
            "-title" {
358
                incr ind
359
                set _titre [lindex $args $ind]
360
                incr ind
361
            }
362
            "-ok" {
363
                incr ind
364
                set _open [lindex $args $ind]
365
                incr ind
366
            }
367
            "-open" {
368
                incr ind
369
                set _expand [lindex $args $ind]
370
                incr ind
371
            }
372
            "-cancel" {
373
                incr ind
374
                set _cancel [lindex $args $ind]
375
                incr ind
376
            }
377
            "-msg1" {
378
                incr ind
379
                set _ldir [lindex $args $ind]
380
                incr ind
381
            }
382
            "-msg2" {
383
                incr ind
384
                set _ldnam [lindex $args $ind]
385
                incr ind
386
            }
387
            default {
388
                puts "unknown option [lindex $args $ind]"
389
                return ""
390
            }
391
        }
392
    }
393
 
394
    #
395
    # variables et data
396
    #
397
    set tk_getDirectory(fini) 0
398
 
399
    image create bitmap tk_getDirectory:b_up -data "
400
    #define up_width 31
401
    #define up_height 23
402
    static unsigned char up_bits[] = {
403
        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
404
        0x00, 0x00, 0x00, 0x80, 0x00, 0x3f, 0x00, 0x80, 0x80, 0x40, 0x00, 0x80,
405
        0x40, 0x80, 0x00, 0x80, 0xe0, 0xff, 0xff, 0x83, 0x20, 0x00, 0x00, 0x82,
406
        0x20, 0x04, 0x00, 0x82, 0x20, 0x0e, 0x00, 0x82, 0x20, 0x1f, 0x00, 0x82,
407
        0x20, 0x04, 0x00, 0x82, 0x20, 0x04, 0x00, 0x82, 0x20, 0x04, 0x00, 0x82,
408
        0x20, 0xfc, 0x0f, 0x82, 0x20, 0x00, 0x00, 0x82, 0x20, 0x00, 0x00, 0x82,
409
        0xe0, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
410
        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80};"
411
 
412
    image create bitmap tk_getDirectory:b_dir -background #ffff80 -data "
413
    #define dir_width 17
414
    #define dir_height 16
415
    static unsigned char dir_bits[] = {
416
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x10, 0x02, 0x00,
417
        0x08, 0x04, 0x00, 0xfc, 0x7f, 0x00, 0x04, 0x40, 0x00, 0x04, 0x40, 0x00,
418
        0x04, 0x40, 0x00, 0x04, 0x40, 0x00, 0x04, 0x40, 0x00, 0x04, 0x40, 0x00,
419
        0x04, 0x40, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};" \
420
                -maskdata "
421
    #define dirm_width 17
422
    #define dirm_height 16
423
    static unsigned char dirm_bits[] = {
424
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0xf0, 0x03, 0x00,
425
        0xf8, 0x07, 0x00, 0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00,
426
        0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00,
427
        0xfc, 0x7f, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"
428
 
429
    switch -exact $tcl_platform(platform) {
430
        unix {
431
            set tk_getDirectory(myfont) \
432
               -adobe-helvetica-bold-r-normal-*-12-120-75-75-p-70-iso8859-1
433
        }
434
        windows {
435
            set tk_getDirectory(myfont) {Courier 12}
436
        }
437
    }
438
 
439
    #
440
    # widgets
441
    #
442
    if {[winfo exists .dirsel]} {destroy .dirsel}
443
    toplevel .dirsel
444
    grab set .dirsel
445
    wm geometry .dirsel 500x250
446
    wm title .dirsel $_titre
447
 
448
    frame .dirsel.f1 -relief flat -borderwidth 0
449
    frame .dirsel.f2 -relief sunken -borderwidth 2
450
    frame .dirsel.f3 -relief flat -borderwidth 0
451
    frame .dirsel.f4 -relief flat -borderwidth 0
452
 
453
    pack .dirsel.f1 -fill x
454
    pack .dirsel.f2 -fill both -expand 1 -padx 6 -pady 6
455
    pack .dirsel.f3 -fill x
456
    pack .dirsel.f4 -fill x
457
 
458
    label .dirsel.f1.lab -text $_ldir
459
    menubutton .dirsel.f1.dir -relief raised -indicatoron 1 -anchor w \
460
            -menu .dirsel.f1.dir.m
461
    menu .dirsel.f1.dir.m -tearoff 0
462
    button .dirsel.f1.up -image tk_getDirectory:b_up \
463
        -command tk_getDirectory:UpDir
464
 
465
    pack .dirsel.f1.up -side right -padx 4 -pady 4
466
    pack .dirsel.f1.lab -side left -padx 4 -pady 4
467
    pack .dirsel.f1.dir -side right -padx 4 -pady 4 -fill x -expand 1
468
 
469
    canvas .dirsel.f2.cv -borderwidth 0 -xscrollcommand ".dirsel.f2.sb set" \
470
       -height 10 -bg white
471
    scrollbar .dirsel.f2.sb -command ".dirsel.f2.cv xview" -orient horizontal
472
    pack .dirsel.f2.cv -side top -fill both -expand 1
473
    pack .dirsel.f2.sb -side top -fill x
474
 
475
    .dirsel.f2.cv bind TXT <Any-Button> tk_getDirectory:ClickItem
476
    .dirsel.f2.cv bind IMG <Any-Button> tk_getDirectory:ClickItem
477
 
478
    button .dirsel.f4.open -text $_open \
479
       -command {set tk_getDirectory(fini) 1}
480
    button .dirsel.f4.cancel -text $_cancel \
481
       -command {set tk_getDirectory(fini) -1}
482
    pack .dirsel.f4.open -side left -padx 25 -pady 4
483
    pack .dirsel.f4.cancel -side right -padx 25 -pady 4
484
 
485
    # Withdraw the window, then update all the geometry information
486
    # so we know how big it wants to be, then center the window in the
487
    # display and de-iconify it.
488
 
489
    wm withdraw .dirsel
490
    update
491
    set p [winfo parent .dirsel]
492
    regsub -all {\+\-} [wm geometry $p] {-} geom
493
    scan $geom %dx%d%d%d pw ph px py
494
    set x [expr {$px + ($pw - 500)/2}]
495
    set y [expr {$py + ($ph - 250)/2}]
496
    if {$x<0} {set x 0}
497
    if {$y<0} {set y 0}
498
    wm geom .dirsel +$x+$y
499
    wm deiconify .dirsel
500
 
501
    #
502
    # realwork
503
    #
504
    tk_getDirectory:ShowDir $tk_getDirectory(curdir)
505
 
506
    #
507
    # wait user
508
    #
509
    tkwait variable tk_getDirectory(fini)
510
 
511
    if { $tk_getDirectory(fini) == 1 } {
512
        set retval [.dirsel.f1.dir cget -text]
513
    } else {
514
        set retval ""
515
    }
516
 
517
    destroy .dirsel
518
    global tk_getDirectory_xref
519
    catch {unset tk_getDirectory_xref}
520
#    unset tk_getDirectory
521
    return $retval
522
}
523
 
524
proc tk_getDirectory:ShowDir {curdir} {
525
    global tcl_platform tk_getDirectory tk_getDirectory_xref
526
 
527
    set tk_getDirectory(curdir) $curdir    
528
    .dirsel.f1.dir configure -text $curdir
529
 
530
    set hi [image height tk_getDirectory:b_dir]
531
    set wi [image width tk_getDirectory:b_dir]
532
    incr wi 4
533
    update
534
    set maxy [expr [winfo height .dirsel.f2.cv]-$hi]
535
 
536
    set lidir [list]
537
    foreach file [glob -nocomplain $curdir/*] {
538
        if [ file isdirectory $file ] {
539
            lappend lidir [file tail $file]
540
        }
541
    }
542
    set sldir [lsort $lidir]
543
 
544
    .dirsel.f2.cv delete all
545
    set ind 0
546
    set x 2
547
    set y 2
548
    catch {unset tk_getDirectory_xref}
549
    foreach file $sldir {
550
      set id [.dirsel.f2.cv create image $x $y \
551
              -anchor nw -image tk_getDirectory:b_dir -tags IMG]
552
      set tk_getDirectory_xref($id) $file
553
      set id [.dirsel.f2.cv create text [expr $x+$wi] $y \
554
              -anchor nw -text $file -font $tk_getDirectory(myfont) -tags TXT]
555
      set tk_getDirectory_xref($id) $file
556
      incr y $hi
557
      if {$y>=$maxy} {
558
        set bbox [.dirsel.f2.cv bbox all]
559
        set x [expr [lindex $bbox 2]+10]
560
        set y 2
561
      }
562
    }
563
    .dirsel.f2.cv configure -scrollregion [.dirsel.f2.cv bbox all]
564
 
565
    set curlst [file split $curdir]
566
    set nbr [llength $curlst]
567
 
568
    .dirsel.f1.dir.m delete 0 last
569
    incr nbr -2
570
    for {set ind $nbr} {$ind >= 0} {incr ind -1} {
571
        set tmplst [ lrange $curlst 0 $ind]
572
        set tmpdir [ eval file join $tmplst]
573
        .dirsel.f1.dir.m add command -label $tmpdir \
574
            -command "tk_getDirectory:ShowDir [list $tmpdir]"
575
    }
576
    if {[info exist tk_getDirectory(drives)] == 0} {
577
       update
578
       if {[catch {file volume} tk_getDirectory(drives)]} {
579
          set tk_getDirectory(drives) {}
580
       }
581
    }
582
    if ![string compare $tcl_platform(platform) windows] {
583
        foreach drive $tk_getDirectory(drives) {
584
            .dirsel.f1.dir.m add command -label $drive \
585
                -command "tk_getDirectory:ShowDir [list $drive]"
586
        }
587
    }
588
 
589
}
590
 
591
proc tk_getDirectory:UpDir {} {
592
  set curdir [.dirsel.f1.dir cget -text]
593
  set curlst [file split $curdir]
594
  set nbr [llength $curlst]
595
  if { $nbr < 2 } {
596
    return
597
  }
598
  set tmp [expr $nbr - 2]
599
  set newlst [ lrange $curlst 0 $tmp ]
600
  set newdir [ eval file join $newlst ]
601
  tk_getDirectory:ShowDir $newdir
602
}
603
 
604
proc tk_getDirectory:ClickItem {} {
605
  global tk_getDirectory tk_getDirectory_xref
606
  set id [.dirsel.f2.cv find withtag current]
607
  if {[catch {set tk_getDirectory_xref($id)} dir]} {
608
    if {[catch {.dirsel.f2.cv itemcget $id -text} dir]} {
609
      return
610
    }
611
  }
612
  if {[string length $dir]==0} return
613
  tk_getDirectory:ShowDir [file join $tk_getDirectory(curdir) $dir]
614
}
615
 
616
#
617
# End tk_getDirectory widget
618
########################################################################
619
 
620
########################################################################
621
#
622
# This version of msgbox.tcl has been modified in two ways:
623
#
624
#     1.  Color icons are used on Unix displays that have a color
625
#         depth of 4 or more.  Most users like the color icons better.
626
#
627
#     2.  The button on error dialog boxes says "Bummer" instead of
628
#         "OK", because errors are not ok.
629
#
630
# Other than that, the code is identical and should be fully
631
# backwards compatible.
632
#
633
 
634
image create bitmap tkPriv:b1 -foreground black \
635
-data "#define b1_width 32\n#define b1_height 32
636
static unsigned char q1_bits[] = {
637
   0x00, 0xf8, 0x1f, 0x00, 0x00, 0x07, 0xe0, 0x00, 0xc0, 0x00, 0x00, 0x03,
638
   0x20, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10,
639
   0x04, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40,
640
   0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,
641
   0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,
642
   0x01, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40,
643
   0x04, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08,
644
   0x60, 0x00, 0x00, 0x04, 0x80, 0x03, 0x80, 0x03, 0x00, 0x0c, 0x78, 0x00,
645
   0x00, 0x30, 0x04, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x40, 0x04, 0x00,
646
   0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00,
647
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"
648
image create bitmap tkPriv:b2 -foreground white \
649
-data "#define b2_width 32\n#define b2_height 32
650
static unsigned char b2_bits[] = {
651
   0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x00,
652
   0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0x0f,
653
   0xf8, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f,
654
   0xfe, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x7f,
655
   0xfe, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x7f,
656
   0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f,
657
   0xf8, 0xff, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0x07,
658
   0x80, 0xff, 0xff, 0x03, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0xf0, 0x07, 0x00,
659
   0x00, 0xc0, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00,
660
   0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
661
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"
662
image create bitmap tkPriv:q -foreground blue \
663
-data "#define q_width 32\n#define q_height 32
664
static unsigned char q_bits[] = {
665
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00,
667
   0x00, 0x10, 0x0f, 0x00, 0x00, 0x18, 0x1e, 0x00, 0x00, 0x38, 0x1e, 0x00,
668
   0x00, 0x38, 0x1e, 0x00, 0x00, 0x10, 0x0f, 0x00, 0x00, 0x80, 0x07, 0x00,
669
   0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00,
670
   0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00,
671
   0x00, 0xe0, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"
676
image create bitmap tkPriv:i -foreground blue \
677
-data "#define i_width 32\n#define i_height 32
678
static unsigned char i_bits[] = {
679
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680
   0x00, 0xe0, 0x01, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00,
681
   0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682
   0x00, 0xf8, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00,
683
   0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00,
684
   0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
685
   0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"
690
image create bitmap tkPriv:w1 -foreground black \
691
-data "#define w1_width 32\n#define w1_height 32
692
static unsigned char w1_bits[] = {
693
   0x00, 0x80, 0x01, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x20, 0x04, 0x00,
694
   0x00, 0x10, 0x04, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00,
695
   0x00, 0x08, 0x10, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x04, 0x20, 0x00,
696
   0x00, 0x02, 0x20, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x01, 0x40, 0x00,
697
   0x00, 0x01, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x01,
698
   0x40, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x02,
699
   0x20, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x08,
700
   0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x10,
701
   0x04, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x40,
702
   0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x20,
703
   0xfc, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00};"
704
image create bitmap tkPriv:w2 -foreground yellow \
705
-data "#define w2_width 32\n#define w2_height 32
706
static unsigned char w2_bits[] = {
707
   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00,
708
   0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x07, 0x00,
709
   0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf8, 0x1f, 0x00,
710
   0x00, 0xfc, 0x1f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xfe, 0x3f, 0x00,
711
   0x00, 0xfe, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00,
712
   0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x01, 0xc0, 0xff, 0xff, 0x01,
713
   0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
714
   0xf0, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
715
   0xf8, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0xff, 0x3f,
716
   0xfe, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x1f,
717
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"
718
image create bitmap tkPriv:w3 -foreground black \
719
-data "#define w3_width 32\n#define w3_height 32
720
static unsigned char w3_bits[] = {
721
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724
   0x00, 0xc0, 0x03, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
725
   0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
726
   0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00,
727
   0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00,
728
   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00,
729
   0x00, 0xc0, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
730
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};"
732
 
733
# tkMessageBox --
734
#
735
#       Pops up a messagebox with an application-supplied message with
736
#       an icon and a list of buttons. This procedure will be called
737
#       by tk_messageBox if the platform does not have native
738
#       messagebox support, or if the particular type of messagebox is
739
#       not supported natively.
740
#
741
#       This procedure is a private procedure shouldn't be called
742
#       directly. Call tk_messageBox instead.
743
#
744
#       See the user documentation for details on what tk_messageBox does.
745
#
746
proc tkMessageBox {args} {
747
    global tkPriv tcl_platform
748
 
749
    set w tkPrivMsgBox
750
    upvar #0 $w data
751
 
752
    #
753
    # The default value of the title is space (" ") not the empty string
754
    # because for some window managers, a 
755
    #           wm title .foo ""
756
    # causes the window title to be "foo" instead of the empty string.
757
    #
758
    set specs {
759
        {-default "" "" ""}
760
        {-icon "" "" "info"}
761
        {-message "" "" ""}
762
        {-parent "" "" .}
763
        {-title "" "" " "}
764
        {-type "" "" "ok"}
765
    }
766
 
767
    tclParseConfigSpec $w $specs "" $args
768
 
769
    if {[lsearch {info warning error question} $data(-icon)] == -1} {
770
        error "invalid icon \"$data(-icon)\", must be error, info, question or warning"
771
    }
772
    if {$tcl_platform(platform) == "macintosh"} {
773
        if {$data(-icon) == "error"} {
774
            set data(-icon) "stop"
775
        } elseif {$data(-icon) == "warning"} {
776
            set data(-icon) "caution"
777
        } elseif {$data(-icon) == "info"} {
778
            set data(-icon) "note"
779
        }
780
    }
781
 
782
    if {![winfo exists $data(-parent)]} {
783
        error "bad window path name \"$data(-parent)\""
784
    }
785
 
786
    case $data(-type) {
787
        abortretryignore {
788
            set buttons {
789
                {abort  -width 6 -text Abort -under 0}
790
                {retry  -width 6 -text Retry -under 0}
791
                {ignore -width 6 -text Ignore -under 0}
792
            }
793
        }
794
        ok {
795
            if {$data(-icon) == "error"} {
796
                set buttons {
797
                    {ok -width 6 -text Bummer -under 0}
798
                }
799
            } else {
800
                set buttons {
801
                    {ok -width 6 -text OK -under 0}
802
                }
803
            }
804
            if {$data(-default) == ""} {
805
                set data(-default) "ok"
806
            }
807
        }
808
        okcancel {
809
            set buttons {
810
                {ok     -width 6 -text OK     -under 0}
811
                {cancel -width 6 -text Cancel -under 0}
812
            }
813
        }
814
        retrycancel {
815
            set buttons {
816
                {retry  -width 6 -text Retry  -under 0}
817
                {cancel -width 6 -text Cancel -under 0}
818
            }
819
        }
820
        yesno {
821
            set buttons {
822
                {yes    -width 6 -text Yes -under 0}
823
                {no     -width 6 -text No  -under 0}
824
            }
825
        }
826
        yesnocancel {
827
            set buttons {
828
                {yes    -width 6 -text Yes -under 0}
829
                {no     -width 6 -text No  -under 0}
830
                {cancel -width 6 -text Cancel -under 0}
831
            }
832
        }
833
        default {
834
            error "invalid message box type \"$data(-type)\", must be abortretryignore, ok, okcancel, retrycancel, yesno or yesnocancel"
835
        }
836
    }
837
 
838
    if {[string compare $data(-default) ""]} {
839
        set valid 0
840
        foreach btn $buttons {
841
            if {![string compare [lindex $btn 0] $data(-default)]} {
842
                set valid 1
843
                break
844
            }
845
        }
846
        if {!$valid} {
847
            error "invalid default button \"$data(-default)\""
848
        }
849
    }
850
 
851
    # 2. Set the dialog to be a child window of $parent
852
    #
853
    #
854
    if {[string compare $data(-parent) .]} {
855
        set w $data(-parent).__tk__messagebox
856
    } else {
857
        set w .__tk__messagebox
858
    }
859
 
860
    # 3. Create the top-level window and divide it into top
861
    # and bottom parts.
862
 
863
    catch {destroy $w}
864
    toplevel $w -class Dialog
865
    wm title $w $data(-title)
866
    wm iconname $w Dialog
867
    wm protocol $w WM_DELETE_WINDOW { }
868
    wm transient $w $data(-parent)
869
    if {$tcl_platform(platform) == "macintosh"} {
870
        unsupported1 style $w dBoxProc
871
    }
872
 
873
    frame $w.bot
874
    pack $w.bot -side bottom -fill both
875
    frame $w.top
876
    pack $w.top -side top -fill both -expand 1
877
    if {$tcl_platform(platform) != "macintosh"} {
878
        $w.bot configure -relief raised -bd 1
879
        $w.top configure -relief raised -bd 1
880
    }
881
 
882
    # 4. Fill the top part with bitmap and message (use the option
883
    # database for -wraplength so that it can be overridden by
884
    # the caller).
885
 
886
    option add *Dialog.msg.wrapLength 3i widgetDefault
887
    label $w.msg -justify left -text $data(-message)
888
    catch {$w.msg configure -font \
889
                -Adobe-Times-Medium-R-Normal--*-180-*-*-*-*-*-*
890
    }
891
    pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m
892
    if {$data(-icon) != ""} {
893
        if {$tcl_platform(platform)=="macintosh" || [winfo depth $w]<4} {
894
            label $w.bitmap -bitmap $data(-icon)
895
        } else {
896
            canvas $w.bitmap -width 32 -height 32 -highlightthickness 0
897
            switch $data(-icon) {
898
                error {
899
                    $w.bitmap create oval 0 0 31 31 -fill red -outline black
900
                    $w.bitmap create line 9 9 23 23 -fill white -width 4
901
                    $w.bitmap create line 9 23 23 9 -fill white -width 4
902
                }
903
                info {
904
                    $w.bitmap create image 0 0 -anchor nw -image tkPriv:b1
905
                    $w.bitmap create image 0 0 -anchor nw -image tkPriv:b2
906
                    $w.bitmap create image 0 0 -anchor nw -image tkPriv:i
907
                }
908
                question {
909
                    $w.bitmap create image 0 0 -anchor nw -image tkPriv:b1
910
                    $w.bitmap create image 0 0 -anchor nw -image tkPriv:b2
911
                    $w.bitmap create image 0 0 -anchor nw -image tkPriv:q
912
                }
913
                default {
914
                    $w.bitmap create image 0 0 -anchor nw -image tkPriv:w1
915
                    $w.bitmap create image 0 0 -anchor nw -image tkPriv:w2
916
                    $w.bitmap create image 0 0 -anchor nw -image tkPriv:w3
917
                }
918
            }
919
        }
920
        pack $w.bitmap -in $w.top -side left -padx 3m -pady 3m
921
    }
922
 
923
    # 5. Create a row of buttons at the bottom of the dialog.
924
 
925
    set i 0
926
    foreach but $buttons {
927
        set name [lindex $but 0]
928
        set opts [lrange $but 1 end]
929
        if {![string compare $opts {}]} {
930
            # Capitalize the first letter of $name
931
            set capName \
932
                [string toupper \
933
                    [string index $name 0]][string range $name 1 end]
934
            set opts [list -text $capName]
935
        }
936
 
937
        eval button $w.$name $opts -command [list "set tkPriv(button) $name"]
938
 
939
        if {![string compare $name $data(-default)]} {
940
            catch {$w.$name configure -default active}
941
        }
942
        pack $w.$name -in $w.bot -side left -expand 1 \
943
            -padx 3m -pady 2m
944
 
945
        # create the binding for the key accelerator, based on the underline
946
        #
947
        set underIdx [$w.$name cget -under]
948
        if {$underIdx >= 0} {
949
            set key [string index [$w.$name cget -text] $underIdx]
950
            bind $w <Alt-[string tolower $key]>  "$w.$name invoke"
951
            bind $w <Alt-[string toupper $key]>  "$w.$name invoke"
952
        }
953
        incr i
954
    }
955
 
956
    # 6. Create a binding for <Return> on the dialog if there is a
957
    # default button.
958
 
959
    if {[string compare $data(-default) ""]} {
960
        bind $w <Return> "tkButtonInvoke $w.$data(-default)"
961
    }
962
 
963
    # 7. Withdraw the window, then update all the geometry information
964
    # so we know how big it wants to be, then center the window in the
965
    # display and de-iconify it.
966
 
967
    wm withdraw $w
968
    update idletasks
969
    set p [winfo parent $w]
970
    regsub -all {\+\-} [wm geometry $p] {-} geom
971
    scan $geom %dx%d%d%d pw ph px py
972
    set x [expr {$px + ($pw - [winfo reqwidth $w])/2}]
973
    set y [expr {$py + ($ph - [winfo reqheight $w])/2}]
974
    if {$x<0} {set x 0}
975
    if {$y<0} {set y 0}
976
    wm geom $w +$x+$y
977
    wm deiconify $w
978
 
979
    # 8. Set a grab and claim the focus too.
980
 
981
    set oldFocus [focus]
982
    set oldGrab [grab current $w]
983
    if {$oldGrab != ""} {
984
        set grabStatus [grab status $oldGrab]
985
    }
986
    grab $w
987
    if {[string compare $data(-default) ""]} {
988
        focus $w.$data(-default)
989
    } else {
990
        focus $w
991
    }
992
 
993
    # 9. Wait for the user to respond, then restore the focus and
994
    # return the index of the selected button.  Restore the focus
995
    # before deleting the window, since otherwise the window manager
996
    # may take the focus away so we can't redirect it.  Finally,
997
    # restore any grab that was in effect.
998
 
999
    tkwait variable tkPriv(button)
1000
    catch {focus $oldFocus}
1001
    destroy $w
1002
    if {$oldGrab != ""} {
1003
        if {$grabStatus == "global"} {
1004
            grab -global $oldGrab
1005
        } else {
1006
            grab $oldGrab
1007
        }
1008
    }
1009
    return $tkPriv(button)
1010
}
1011
#
1012
##################### End Tk_MessageBox ############################
1013
 
1014
#################### Begin Console Wdiget ##########################
1015
# A console widget for Tcl/Tk.  Invoke OpenConsole with a window name
1016
# and prompt string to get a new top-level window that allows the
1017
# user to enter tcl commands.  This is mainly useful for testing and
1018
# debugging.
1019
#
1020
# Copyright (C) 1998 D. Richard Hipp
1021
#
1022
# This library is free software; you can redistribute it and/or
1023
# modify it under the terms of the GNU Library General Public
1024
# License as published by the Free Software Foundation; either
1025
# version 2 of the License, or (at your option) any later version.
1026
#
1027
# This library is distributed in the hope that it will be useful,
1028
# but WITHOUT ANY WARRANTY; without even the implied warranty of
1029
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1030
# Library General Public License for more details.
1031
# 
1032
# You should have received a copy of the GNU Library General Public
1033
# License along with this library; if not, write to the
1034
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1035
# Boston, MA  02111-1307, USA.
1036
#
1037
# Author contact information:
1038
#   drh@acm.org
1039
#   http://www.hwaci.com/drh/
1040
 
1041
 
1042
proc OpenConsole {w prompt} {
1043
  upvar #0 $w.t v
1044
  if {[winfo exists $w]} {destroy $w}
1045
  catch {unset v}
1046
  toplevel $w
1047
  wm title $w { Vertical Console }
1048
  wm iconname $w {Console}
1049
  button $w.quit -text Dismiss -command "destroy $w"
1050
  pack $w.quit -side bottom
1051
  scrollbar $w.sb -orient vertical -command "$w.t yview"
1052
  pack $w.sb -side right -fill y
1053
  text $w.t -font fixed -yscrollcommand "$w.sb set"
1054
  pack $w.t -side right -fill both -expand 1
1055
  bindtags $w.t Console
1056
  set v(text) $w.t
1057
  set v(history) 0
1058
  set v(historycnt) 0
1059
  set v(current) -1
1060
  set v(prompt) $prompt
1061
  set v(plength) [string length $v(prompt)]
1062
  $w.t insert end $v(prompt)
1063
  $w.t mark set insert end
1064
  $w.t tag config ok -foreground blue
1065
  $w.t tag config err -foreground red
1066
  after idle "focus $w.t"
1067
}
1068
 
1069
bind Console <1> {focus %W}
1070
bind Console <KeyPress> {conInsert %W %A}
1071
bind Console <Left> {conLeft %W}
1072
bind Console <Control-b> {conLeft %W}
1073
bind Console <Right> {conRight %W}
1074
bind Console <Control-f> {conRight %W}
1075
bind Console <BackSpace> {conBackspace %W}
1076
bind Console <Control-h> {conBackspace %W}
1077
bind Console <Delete> {conDelete %W}
1078
bind Console <Control-d> {conDelete %W}
1079
bind Console <Home> {conHome %W}
1080
bind Console <Control-a> {conHome %W}
1081
bind Console <End> {conEnd %W}
1082
bind Console <Control-e> {conEnd %W}
1083
bind Console <Return> {conEnter %W}
1084
bind Console <KP_Enter> {conEnter %W}
1085
bind Console <Up> {conPrior %W}
1086
bind Console <Control-p> {conPrior %W}
1087
bind Console <Down> {conNext %W}
1088
bind Console <Control-n> {conNext %W}
1089
 
1090
# Insert a single character at the insertion cursor
1091
#
1092
proc conInsert {w a} {
1093
  $w insert insert $a
1094
}
1095
 
1096
# Move the cursor one character to the left
1097
#
1098
proc conLeft {w} {
1099
  upvar #0 $w v
1100
  scan [$w index insert] %d.%d row col
1101
  if {$col>$v(plength)} {
1102
    $w mark set insert "insert -1c"
1103
  }
1104
}
1105
 
1106
# Erase the character to the left of the cursor
1107
#
1108
proc conBackspace {w} {
1109
  upvar #0 $w v
1110
  scan [$w index insert] %d.%d row col
1111
  if {$col>$v(plength)} {
1112
    $w delete {insert -1c}
1113
  }
1114
}
1115
 
1116
# Move the cursor one character to the right
1117
#
1118
proc conRight {w} {
1119
  $w mark set insert "insert +1c"
1120
}
1121
 
1122
# Erase the character to the right of the cursor
1123
#
1124
proc conDelete w {
1125
  $w delete insert
1126
}
1127
 
1128
# Move the cursor to the beginning of the current line
1129
#
1130
proc conHome w {
1131
  upvar #0 $w v
1132
  scan [$w index insert] %d.%d row col
1133
  $w mark set insert $row.$v(plength)
1134
}
1135
 
1136
# Move the cursor to the end of the current line
1137
#
1138
proc conEnd w {
1139
  $w mark set insert {insert lineend}
1140
}
1141
 
1142
# Called when "Enter" is pressed.  Do something with the line
1143
# of text that was entered.
1144
#
1145
proc conEnter w {
1146
  upvar #0 $w v
1147
  scan [$w index insert] %d.%d row col
1148
  set start $row.$v(plength)
1149
  set line [$w get $start "$start lineend"]
1150
  if {$v(historycnt)>0} {
1151
    set last [lindex $v(history) [expr $v(historycnt)-1]]
1152
    if {[string compare $last $line]} {
1153
      lappend v(history) $line
1154
      incr v(historycnt)
1155
    }
1156
  } else {
1157
    set v(history) [list $line]
1158
    set v(historycnt) 1
1159
  }
1160
  set v(current) $v(historycnt)
1161
  $w insert end \n
1162
  if {[catch {uplevel #0 $line} res]} {
1163
    $w insert end $res\n err
1164
  } elseif {[string length $res]>0} {
1165
    $w insert end $res\n ok
1166
  }
1167
  $w insert end $v(prompt)
1168
  $w mark set insert end
1169
  $w yview insert
1170
}
1171
 
1172
# Change the line to the previous line
1173
#
1174
proc conPrior w {
1175
  upvar #0 $w v
1176
  if {$v(current)<=0} return
1177
  incr v(current) -1
1178
  set line [lindex $v(history) $v(current)]
1179
  conSetLine $w $line
1180
}
1181
 
1182
# Change the line to the next line
1183
#
1184
proc conNext w {
1185
  upvar #0 $w v
1186
  if {$v(current)>=$v(historycnt)} return
1187
  incr v(current) 1
1188
  set line [lindex $v(history) $v(current)]
1189
  conSetLine $w $line
1190
}
1191
 
1192
# Change the contents of the entry line
1193
#
1194
proc conSetLine {w line} {
1195
  upvar #0 $w v
1196
  scan [$w index insert] %d.%d row col
1197
  set start $row.$v(plength)
1198
  $w delete $start end
1199
  $w insert end $line
1200
  $w mark set insert end
1201
  $w yview insert
1202
}
1203
########################### End Console Widget ###########################