home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / devel / tcl / tclx7_31.z / tclx7_31 / tcldev / tclX7.3a-p1 / tktclsrc / tclhelp.tcl < prev    next >
Encoding:
Text File  |  1994-01-11  |  9.4 KB  |  315 lines

  1.  
  2. # tclhelp.tcl --
  3. #
  4. # Tk program to access Extended Tcl & Tk help pages.  Uses internal functions
  5. # of TclX help command.
  6. #------------------------------------------------------------------------------
  7. # Copyright 1993 Karl Lehenbauer and Mark Diekhans.
  8. #
  9. # Permission to use, copy, modify, and distribute this software and its
  10. # documentation for any purpose and without fee is hereby granted, provided
  11. # that the above copyright notice appear in all copies.  Karl Lehenbauer and
  12. # Mark Diekhans make no representations about the suitability of this
  13. # software for any purpose.  It is provided "as is" without express or
  14. # implied warranty.
  15. #------------------------------------------------------------------------------
  16. # $Id: tclhelp.tcl,v 3.2 1994/01/11 05:18:48 markd Exp $
  17. #------------------------------------------------------------------------------
  18.  
  19. #------------------------------------------------------------------------------
  20. # Add a button associated with either a file or directory in the help tree.
  21. # This handles creating frames to hold each row of buttons.  Buttons should
  22. # be delivered in accending row order, and accending column order within each
  23. # row.  Special handling is done for '..'/
  24.  
  25. proc AddButton {parent subject fileName row col} {
  26.  
  27.     # Prep name to use in button and other file info.
  28.  
  29.     set isDir [string match */ $fileName]
  30.     if [string match */ $subject] {
  31.         set subject [csubstr $subject 0 len-1]
  32.     }
  33.     if {$fileName == ".."} {
  34.         set fileName "<Up>"
  35.         set filePath [file dirname $subject]
  36.         set isDir 1
  37.     } else {
  38.         set filePath ${subject}/${fileName}
  39.     }
  40.  
  41.     # Set up a row frame, if needed.
  42.  
  43.     set nframe $parent.row$row
  44.     if {$col == 0} {
  45.         frame $nframe
  46.         pack $nframe -side top -expand 1 -anchor w -fill x
  47.     }
  48.  
  49.     # Set up the button.
  50.  
  51.     set buttonName $nframe.col$col
  52.     if $isDir {
  53.         button $buttonName -text $fileName -width 20 \
  54.             -command "DisplaySubject $filePath"
  55.     } else {
  56.         button $buttonName -text $fileName -width 20 \
  57.             -command "DisplayPage $filePath"
  58.     }
  59.     pack $buttonName -side left -anchor w
  60. }
  61.  
  62. #------------------------------------------------------------------------------
  63. # Create a frame to hold buttons for the specified list of either help files
  64. # or directories.
  65.  
  66. proc ButtonFrame {w title subject fileList} {
  67.     frame $w
  68.     label $w.label -relief flat -text $title -background SlateGray1
  69.     pack $w.label -side top -fill both
  70.     frame $w.buttons
  71.     pack $w.buttons -side top -expand 1 -anchor w
  72.     set col 0
  73.     set row 0
  74.     while {![lempty $fileList]} {
  75.         AddButton $w.buttons $subject [lvarpop fileList] $row $col
  76.         if {[incr col] >= 5} {
  77.             incr row
  78.             set col 0
  79.         }
  80.     }
  81. }
  82.  
  83. #------------------------------------------------------------------------------
  84. # Display the panels contain the subjects (directories) and the help files for
  85. # a given directory.
  86.  
  87. proc DisplaySubject {subject} {
  88.  
  89.     help:ListSubject $subject [help:ConvertPath $subject] subjects pages
  90.     if {$subject != "/"} {
  91.         lvarpush subjects ".."
  92.     }
  93.  
  94.     set frame .tkhelp.pick
  95.     catch {destroy $frame}
  96.     frame $frame
  97.     pack $frame -side top -fill x
  98.     
  99.     ButtonFrame $frame.subjects "Subjects available in $subject" \
  100.         $subject $subjects
  101.     pack $frame.subjects -side top -fill x
  102.  
  103.     ButtonFrame $frame.pages "Help files available in $subject" \
  104.         $subject $pages
  105.     pack $frame.pages -side top -fill x
  106. }
  107.  
  108. #------------------------------------------------------------------------------
  109. # Display a file in a top-level text window.
  110.  
  111. proc DisplayPage {page} {
  112.     set fileName [file tail $page]
  113.  
  114.     set w ".tkhelp-[translit "." "_" $page]"
  115.  
  116.     catch {destroy $w}
  117.     toplevel $w
  118.  
  119.     wm title $w "Help on '$page'"
  120.     wm iconname $w "Help: $page"
  121.     wm minsize $w 1 1
  122.     frame $w.frame -borderwidth 10
  123.  
  124.     scrollbar $w.frame.yscroll -relief sunken \
  125.         -command "$w.frame.page yview"
  126.     text $w.frame.page -yscroll "$w.frame.yscroll set" \
  127.         -width 80 -height 20 -relief sunken -wrap word
  128.     pack $w.frame.yscroll -side right -fill y
  129.     pack $w.frame.page -side top -expand 1 -fill both
  130.  
  131.     if [catch {
  132.             set contents [read_file [help:ConvertPath $page]]
  133.         } msg] {
  134.         set contents $msg
  135.     }
  136.     $w.frame.page insert 0.0 $contents
  137.     $w.frame.page configure -state disabled
  138.  
  139.     button $w.dismiss -text Dismiss -command "destroy $w"
  140.     pack $w.frame -side top -fill both -expand 1
  141.     pack $w.dismiss -side bottom -fill x
  142. }
  143.  
  144. #------------------------------------------------------------------------------
  145. # Set up the apropos panel.
  146.  
  147. proc AproposPanel {} {
  148.     global aproposEntryNumber aproposReferenceFrame referenceFrameItem
  149.  
  150.     set aproposEntryNumber 0
  151.     catch {destory .apropos}
  152.     toplevel .apropos
  153.     wm minsize .apropos 1 1
  154.     frame .apropos.entryFrame
  155.     pack .apropos.entryFrame -side top -fill x
  156.  
  157.     label .apropos.entryFrame.label -text "Search for"
  158.     pack .apropos.entryFrame.label -side left
  159.  
  160.     entry .apropos.entryFrame.entry -relief sunken
  161.     pack .apropos.entryFrame.entry -side left -fill x -expand 1
  162.  
  163.     bind .apropos.entryFrame.entry <Return> PerformAproposSearch
  164.  
  165.     frame .apropos.canvasFrame
  166.     set w .apropos.canvasFrame
  167.  
  168.     canvas $w.canvas -yscroll "$w.yscroll set" -xscroll "$w.xscroll set" \
  169.         -width 15c -height 5c -relief sunken
  170.  
  171.     scrollbar $w.yscroll -relief sunken \
  172.         -command "$w.canvas yview"
  173.  
  174.     scrollbar $w.xscroll -relief sunken -orient horiz \
  175.         -command "$w.canvas xview"
  176.  
  177.     pack $w.xscroll -side bottom -fill x
  178.     pack $w.yscroll -side right -fill y
  179.     pack $w.canvas -in $w -expand yes -fill both
  180.     pack $w -side top -expand yes -fill both
  181.  
  182.     # put in the dismiss button
  183.     set w .apropos.buttonFrame
  184.     frame $w
  185.     pack $w -side top -fill x
  186.     button $w.dismiss -text Dismiss -command "destroy .apropos"
  187.     pack $w.dismiss -side bottom -fill x
  188. }
  189.  
  190. #---------------------------------------------------------------------------
  191. #put a line in the reference display for this apropos entry we've discovered
  192. #
  193. proc DisplayAproposReference {path description} {
  194.     global aproposEntryNumber aproposReferenceFrame
  195.  
  196.     set frame $aproposReferenceFrame.e$aproposEntryNumber
  197.     frame $frame
  198.     pack $frame -side top -anchor w
  199.  
  200.     button $frame.button -text $path -width 30 \
  201.         -command "DisplayPage /$path"
  202.     pack $frame.button -side left
  203.  
  204.     label $frame.label -text $description
  205.     pack $frame.label -side left
  206.  
  207.     incr aproposEntryNumber
  208. }
  209.  
  210. #---------------------------------------------------------------------------
  211. #the actual search is cadged from "apropos" in the tclx help system
  212. #
  213. proc PerformAproposSearch {} {
  214.     global TCLXENV referenceFrameItem aproposEntryNumber aproposReferenceFrame
  215.  
  216.     #  start variables and clean up any residue from previous searches
  217.     set w .apropos.canvasFrame
  218.     set aproposEntryNumber 0
  219.     .apropos.canvasFrame.canvas delete all
  220.     set aproposReferenceFrame $w.canvas.frame
  221.     catch "destroy $aproposReferenceFrame"
  222.     catch "destroy .apropos.canvasFrame.failed"
  223.  
  224.     # create the frame we'll pack matches into and put it into the canvas
  225.     frame $aproposReferenceFrame
  226.     set referenceFrameItem \
  227.         [$w.canvas create window 2 2 -window $aproposReferenceFrame -anchor nw]
  228.  
  229.     set regexp [.apropos.entryFrame.entry get]
  230.     focus none
  231.  
  232.     set TCLXENV(help:lineCnt) 0
  233.  
  234.     # set up scan context
  235.     set ch [scancontext create]
  236.     scanmatch -nocase $ch $regexp {
  237.         set path [lindex $matchInfo(line) 0]
  238.         set desc [lrange $matchInfo(line) 1 end]
  239.         DisplayAproposReference $path $desc
  240.     }
  241.  
  242.     # perform search
  243.     foreach dir [help:RootDirs] {
  244.         foreach brief [glob -nocomplain $dir/*.brf] {
  245.             set briefFH [open $brief]
  246.             scanfile $ch $briefFH
  247.             close $briefFH
  248.         }
  249.     }
  250.  
  251.     # delete scan context
  252.     scancontext delete $ch
  253.  
  254.     # force display to update so we can find out our bounding box
  255.     update
  256.  
  257.     # if nothing matched, complain
  258.     if {$aproposEntryNumber == 0} {
  259.         label $aproposReferenceFrame.failed -text "NOTHING MATCHED."
  260.         pack $aproposReferenceFrame.failed -side left
  261.     }
  262.  
  263.     # set the canvas scrollregion to the size of the bounding box
  264.     lassign [.apropos.canvasFrame.canvas bbox $referenceFrameItem] \
  265.         dummy dummy xSize ySize
  266.     .apropos.canvasFrame.canvas configure -scrollregion \
  267.     "0 0 $xSize $ySize"
  268. }
  269.  
  270. #------------------------------------------------------------------------------
  271. # Set up the command buttons.
  272.  
  273. proc CreateCommandButtons {frameName} {
  274.     frame $frameName
  275.  
  276.     button $frameName.quit -text "Quit" -command exit
  277.     pack $frameName.quit -side left
  278.  
  279.     button $frameName.apropos -text "Apropos" -command AproposPanel
  280.     pack $frameName.apropos -side left
  281. }
  282.  
  283. #------------------------------------------------------------------------------
  284. # Tk base help command for Tcl/Tk/TclX.  Directories in args are pushed on the
  285. # path so that they are included in help search.
  286.  
  287. proc tkhelp addPaths {
  288.     global auto_path
  289.     if ![auto_load help] {
  290.         puts stderr "couldn't auto_load TclX 'help' command"
  291.         exit 255
  292.     }
  293.     foreach dir $addPaths {
  294.         lvarpush auto_path $dir
  295.     }
  296.     CreateCommandButtons .command
  297.     pack .command -side top -fill x
  298.  
  299.     catch {destroy .tkhelp}
  300.     frame .tkhelp
  301.     pack .tkhelp -side top -fill both
  302.  
  303.     DisplaySubject "/"
  304.  
  305. }
  306.  
  307. if !$tcl_interactive {
  308.     if [catch {
  309.         tkhelp $argv
  310.     } msg] {
  311.         tkerror $msg
  312.     }
  313. }
  314.