| 1 | 
# SCCSid "$SunId$ LBL" | 
| 2 | 
# | 
| 3 | 
# Get help from a file, formatted like so: | 
| 4 | 
# | 
| 5 | 
# .category1.topic1 | 
| 6 | 
# | 
| 7 | 
# A bunch of unformatted text... | 
| 8 | 
# | 
| 9 | 
# .category2.topic2 | 
| 10 | 
# | 
| 11 | 
# etc. | 
| 12 | 
# | 
| 13 | 
 | 
| 14 | 
# Calling program should define global help file directory as $helplib | 
| 15 | 
 | 
| 16 | 
proc helplink {win file cat top} {              # Create link for window(s) | 
| 17 | 
        foreach w $win { | 
| 18 | 
                bind $w <Control-Button-1> "gethelp $file $cat $top" | 
| 19 | 
        } | 
| 20 | 
} | 
| 21 | 
 | 
| 22 | 
set curhelp(file) {} | 
| 23 | 
 | 
| 24 | 
proc gethelp {helpfile category topic} {        # Open help window | 
| 25 | 
        global curhelp helpfontwidth | 
| 26 | 
        if {! [winfo exists .helpwin]} {                # Set up window | 
| 27 | 
                toplevel .helpwin -cursor top_left_arrow | 
| 28 | 
                wm minsize .helpwin 500 400 | 
| 29 | 
                wm iconbitmap .helpwin question | 
| 30 | 
                frame .helpwin.but -geometry 150x400 | 
| 31 | 
                pack .helpwin.but -side right -fill none -expand no | 
| 32 | 
                label .helpwin.but.lab -textvariable curhelp(title) | 
| 33 | 
                place .helpwin.but.lab -relx .1667 -rely 0 | 
| 34 | 
                helplink .helpwin.but.lab help help intro | 
| 35 | 
                menubutton .helpwin.but.catb -relief raised -height 1 \ | 
| 36 | 
                                -text Category -menu .helpwin.but.catb.m | 
| 37 | 
                menu .helpwin.but.catb.m | 
| 38 | 
                place .helpwin.but.catb -relx .1667 -rely .1100 \ | 
| 39 | 
                                -relwidth .5000 -relheight .0600 | 
| 40 | 
                helplink .helpwin.but.catb help help category | 
| 41 | 
                menubutton .helpwin.but.topb -relief raised -height 1 \ | 
| 42 | 
                                -text Topic -menu .helpwin.but.topb.m | 
| 43 | 
                menu .helpwin.but.topb.m | 
| 44 | 
                place .helpwin.but.topb -relx .1667 -rely .2200 \ | 
| 45 | 
                                -relwidth .5000 -relheight .0600 | 
| 46 | 
                helplink .helpwin.but.topb help help topic | 
| 47 | 
                button .helpwin.but.srchb -text Grep -relief raised \ | 
| 48 | 
                                -height 1 -command {helpsearch $curhelp(search)} | 
| 49 | 
                place .helpwin.but.srchb -relx .1667 -rely .3500 \ | 
| 50 | 
                                -relwidth .5000 -relheight .0600 | 
| 51 | 
                helplink .helpwin.but.srchb help navigate search | 
| 52 | 
                entry .helpwin.but.srche -relief sunken -insertofftime 0 \ | 
| 53 | 
                                -textvariable curhelp(search) | 
| 54 | 
                place .helpwin.but.srche -relx .1667 -rely .4200 \ | 
| 55 | 
                                -relwidth .6667 -relheight .0600 | 
| 56 | 
                bind .helpwin.but.srche <Return> {set curhelp(msg) {} | 
| 57 | 
                                                        helpupdate} | 
| 58 | 
                helplink .helpwin.but.srche help navigate search | 
| 59 | 
                label .helpwin.but.msg -textvariable curhelp(msg) | 
| 60 | 
                place .helpwin.but.msg -relx .1667 -rely .4800 | 
| 61 | 
                button .helpwin.but.next -text Next -relief raised -height 1 \ | 
| 62 | 
                                -command {eval helphist new $curhelp(next)} | 
| 63 | 
                place .helpwin.but.next -relx .1667 -rely .7500 \ | 
| 64 | 
                                -relwidth .5 -relheight .0600 | 
| 65 | 
                helplink .helpwin.but.next help navigate next | 
| 66 | 
                button .helpwin.but.back -text Back -relief raised -height 1 \ | 
| 67 | 
                                -command "helphist back" | 
| 68 | 
                place .helpwin.but.back -relx .1667 -rely .6500 \ | 
| 69 | 
                                -relwidth .5 -relheight .0600 | 
| 70 | 
                helplink .helpwin.but.back help navigate back | 
| 71 | 
                button .helpwin.but.forw -text Forward -relief raised -height 1\ | 
| 72 | 
                                -command "helphist forward" | 
| 73 | 
                place .helpwin.but.forw -relx .1667 -rely .5500 \ | 
| 74 | 
                                -relwidth .5 -relheight .0600 | 
| 75 | 
                helplink .helpwin.but.forw help navigate forward | 
| 76 | 
                button .helpwin.but.done -text Done -relief raised -height 1 \ | 
| 77 | 
                                -command "destroy .helpwin ; helpopen {}" | 
| 78 | 
                place .helpwin.but.done -relx .1667 -rely .9000 \ | 
| 79 | 
                                -relwidth .5 -relheight .0600 | 
| 80 | 
                helplink .helpwin.but.done help help done | 
| 81 | 
                text .helpwin.txt -wrap word -width 48 -height 20 -bd 2 \ | 
| 82 | 
                        -yscrollcommand ".helpwin.sb set" -relief raised \ | 
| 83 | 
                        -font -*-courier-medium-r-normal--14-*-*-*-*-*-iso8859-1 | 
| 84 | 
                .helpwin.txt tag configure highlight \ | 
| 85 | 
                        -font -*-courier-bold-r-normal--14-*-*-*-*-*-iso8859-1 | 
| 86 | 
                set helpfontwidth 9 | 
| 87 | 
                scrollbar .helpwin.sb -relief flat \ | 
| 88 | 
                                -command ".helpwin.txt yview" | 
| 89 | 
                pack .helpwin.sb -side right -fill y | 
| 90 | 
                pack .helpwin.txt -expand yes -fill both | 
| 91 | 
                helplink .helpwin.sb help helpwin scroll | 
| 92 | 
                helplink .helpwin.txt help helpwin intro | 
| 93 | 
                tkwait visibility .helpwin | 
| 94 | 
        } elseif {! [winfo ismapped .helpwin]} {        # map window | 
| 95 | 
                wm deiconify .helpwin | 
| 96 | 
        } else {                                        # raise window | 
| 97 | 
                raise .helpwin | 
| 98 | 
        } | 
| 99 | 
        focus .helpwin.but.srche | 
| 100 | 
        helpopen $helpfile | 
| 101 | 
        helphist new $category $topic | 
| 102 | 
} | 
| 103 | 
 | 
| 104 | 
proc helpopen fname {                   # open the named help file | 
| 105 | 
        global curhelp helpindex helplib | 
| 106 | 
        if {"$fname" == "$curhelp(file)"} {return} | 
| 107 | 
        if {"$curhelp(file)" != {}} { | 
| 108 | 
                close $curhelp(fid) | 
| 109 | 
                unset curhelp helpindex | 
| 110 | 
        } | 
| 111 | 
        if {[set curhelp(file) $fname] == {}} {return} | 
| 112 | 
        # Complete file name as required | 
| 113 | 
        if {! [info exists helplib]} { | 
| 114 | 
                set helplib /usr/local/lib/tk/help | 
| 115 | 
        } | 
| 116 | 
        if {"[file rootname $fname]" == "$fname"} { | 
| 117 | 
                append fname .hlp | 
| 118 | 
        } | 
| 119 | 
        if {! [string match {[~/.]*} $fname]} { | 
| 120 | 
                set fname $helplib/$fname | 
| 121 | 
        } | 
| 122 | 
        wm title .helpwin $fname | 
| 123 | 
        set curhelp(title) "[string toupper\ | 
| 124 | 
                        [file rootname [file tail $fname]]]  HELP" | 
| 125 | 
        set ifile [file rootname $fname].ndx | 
| 126 | 
        wm iconname .helpwin [string tolower $curhelp(title)] | 
| 127 | 
        .helpwin.txt configure -state normal | 
| 128 | 
        .helpwin.txt delete 1.0 end | 
| 129 | 
        .helpwin.txt insert end "Loading $fname..." | 
| 130 | 
        update | 
| 131 | 
        set curhelp(fid) [open $fname r] | 
| 132 | 
        if {! [file exists $ifile] || | 
| 133 | 
                        [file mtime $fname] > [file mtime $ifile]} { | 
| 134 | 
                set curhelp(catlist) {} | 
| 135 | 
                while {[gets $curhelp(fid) li] >= 0} { | 
| 136 | 
                        if [regexp -nocase {^\.([A-Z][A-Z0-9]*)\.([A-Z][A-Z0-9]*)$} \ | 
| 137 | 
                                        $li dummy cat top] { | 
| 138 | 
                                lappend helpindex([string toupper $cat]) $top | 
| 139 | 
                                set helpindex([string toupper $cat,$top]) \ | 
| 140 | 
                                                [tell $curhelp(fid)] | 
| 141 | 
                                if {[lsearch -exact $curhelp(catlist) $cat] < 0} { | 
| 142 | 
                                        lappend curhelp(catlist) $cat | 
| 143 | 
                                } | 
| 144 | 
                        } | 
| 145 | 
                } | 
| 146 | 
                if {! [catch {set fi [open $ifile w]}]} { | 
| 147 | 
                        writevars $fi {curhelp(catlist) helpindex} | 
| 148 | 
                        close $fi | 
| 149 | 
                        catch {exec chmod 666 $ifile} | 
| 150 | 
                } | 
| 151 | 
        } else { | 
| 152 | 
                source $ifile | 
| 153 | 
        } | 
| 154 | 
        .helpwin.but.catb.m delete 0 last | 
| 155 | 
        foreach cat $curhelp(catlist) { | 
| 156 | 
                .helpwin.but.catb.m add command -label $cat \ | 
| 157 | 
                                -command "helphist new $cat intro" | 
| 158 | 
        } | 
| 159 | 
        set curhelp(category) None | 
| 160 | 
        .helpwin.but.topb.m delete 0 last | 
| 161 | 
        set curhelp(topic) None | 
| 162 | 
        set curhelp(next) {} | 
| 163 | 
        helphist clear | 
| 164 | 
} | 
| 165 | 
 | 
| 166 | 
proc helpgoto {cat top} {               # find selected category and topic | 
| 167 | 
        global curhelp helpindex | 
| 168 | 
        # Capitalize "just in case" | 
| 169 | 
        set cat [string toupper $cat] | 
| 170 | 
        set top [string toupper $top] | 
| 171 | 
        # Change topic menu if category is changed | 
| 172 | 
        set curhelp(topic) $top | 
| 173 | 
        if {"$cat" != "$curhelp(category)"} { | 
| 174 | 
                set curhelp(category) $cat | 
| 175 | 
                .helpwin.but.topb.m delete 0 last | 
| 176 | 
                foreach top $helpindex($cat) { | 
| 177 | 
                        .helpwin.but.topb.m add command -label $top \ | 
| 178 | 
                                -command "helphist new \$curhelp(category) $top" | 
| 179 | 
                } | 
| 180 | 
        } | 
| 181 | 
        helpupdate | 
| 182 | 
} | 
| 183 | 
 | 
| 184 | 
proc helpupdate {} {                    # update help text window | 
| 185 | 
        global curhelp helpindex helpfontwidth | 
| 186 | 
        # Print category and topic | 
| 187 | 
        set linelen [expr "[winfo width .helpwin.txt] / $helpfontwidth - 1"] | 
| 188 | 
        .helpwin.txt configure -state normal | 
| 189 | 
        .helpwin.txt delete 1.0 end | 
| 190 | 
        set titlen [expr [string length $curhelp(category)] + \ | 
| 191 | 
                        [string length $curhelp(topic)] + 1] | 
| 192 | 
        for {set i [expr ($linelen - $titlen)/2]} {[incr i -1] >= 0} {} { | 
| 193 | 
                .helpwin.txt insert end { } | 
| 194 | 
        } | 
| 195 | 
        .helpwin.txt insert end "$curhelp(category) $curhelp(topic)\n" | 
| 196 | 
        .helpwin.txt tag add highlight "1.0 lineend - $titlen c" "1.0 lineend" | 
| 197 | 
        # Search for it in file | 
| 198 | 
        if {"$curhelp(category) $curhelp(topic)" != | 
| 199 | 
                        "[string toupper $curhelp(next)]"} { | 
| 200 | 
                if [info exists helpindex($curhelp(category),$curhelp(topic))] { | 
| 201 | 
                        seek $curhelp(fid) $helpindex($curhelp(category),$curhelp(topic)) | 
| 202 | 
                } else { | 
| 203 | 
                        .helpwin.txt insert end "\nNo such help topic." | 
| 204 | 
                        .helpwin.txt configure -state disabled | 
| 205 | 
                        return ".$curhelp(category).$curhelp(topic) not found\ | 
| 206 | 
                                        in $curhelp(file)" | 
| 207 | 
                } | 
| 208 | 
        } | 
| 209 | 
        # Load help text into our window | 
| 210 | 
        set linepos 0 | 
| 211 | 
        while {[set ll [gets $curhelp(fid) li]] >= 0 && ! [regexp -nocase \ | 
| 212 | 
                        {^\.([A-Z][A-Z0-9]*)\.([A-Z][A-Z0-9]*)$} \ | 
| 213 | 
                        $li dummy cat top]} { | 
| 214 | 
                if {$ll == 0} {                         # paragraph | 
| 215 | 
                        if $linepos { | 
| 216 | 
                                .helpwin.txt insert end "\n\n" | 
| 217 | 
                                set linepos 0 | 
| 218 | 
                        } else { | 
| 219 | 
                                .helpwin.txt insert end "\n" | 
| 220 | 
                        } | 
| 221 | 
                } else {                                # line | 
| 222 | 
                        .helpwin.txt insert end $li | 
| 223 | 
                        incr linepos $ll | 
| 224 | 
                        .helpwin.txt insert end { } | 
| 225 | 
                        incr linepos | 
| 226 | 
                        # Highlight search string match | 
| 227 | 
                        if {"$curhelp(search)" != {}} { | 
| 228 | 
                                if [regexp -nocase -indices \ | 
| 229 | 
                                                $curhelp(search) $li mi] { | 
| 230 | 
                                        .helpwin.txt tag add highlight\ | 
| 231 | 
                                                        "end - 1 c - $ll c\ | 
| 232 | 
                                                        + [lindex $mi 0] c"\ | 
| 233 | 
                                                        "end - $ll c\ | 
| 234 | 
                                                        + [lindex $mi 1] c" | 
| 235 | 
                                } | 
| 236 | 
                        } | 
| 237 | 
                        # Add extra space at the end of a sentence | 
| 238 | 
                        if [regexp {[.?!:][)"']?$} $li] { | 
| 239 | 
                                .helpwin.txt insert end { } | 
| 240 | 
                                incr linepos | 
| 241 | 
                        } | 
| 242 | 
                } | 
| 243 | 
        } | 
| 244 | 
        # Highlight next category and topic | 
| 245 | 
        if {$ll > 0} { | 
| 246 | 
                .helpwin.txt insert end "Next:  $cat $top" | 
| 247 | 
                .helpwin.txt tag add highlight "end linestart" end | 
| 248 | 
                set curhelp(next) "$cat $top" | 
| 249 | 
                .helpwin.but.next configure -state normal | 
| 250 | 
        } else { | 
| 251 | 
                .helpwin.but.next configure -state disabled | 
| 252 | 
        } | 
| 253 | 
        .helpwin.txt configure -state disabled | 
| 254 | 
        return {} | 
| 255 | 
} | 
| 256 | 
 | 
| 257 | 
proc helphist {op args} {               # access help history list | 
| 258 | 
        global curhelp | 
| 259 | 
        switch -exact $op { | 
| 260 | 
                clear { | 
| 261 | 
                        set curhelp(histlst) {} | 
| 262 | 
                        set curhelp(histpos) 0 | 
| 263 | 
                        set gotoit 0 | 
| 264 | 
                } | 
| 265 | 
                new { | 
| 266 | 
                        set curhelp(histpos) \ | 
| 267 | 
                                        [expr [llength $curhelp(histlst)] - 1] | 
| 268 | 
                        if {"[string toupper [lindex $curhelp(histlst) \ | 
| 269 | 
                                        $curhelp(histpos)]]" | 
| 270 | 
                                        != "[string toupper $args]"} { | 
| 271 | 
                                lappend curhelp(histlst) $args | 
| 272 | 
                                incr curhelp(histpos) | 
| 273 | 
                        } | 
| 274 | 
                        set gotoit 1 | 
| 275 | 
                } | 
| 276 | 
                append { | 
| 277 | 
                        lappend curhelp(histlst) $args | 
| 278 | 
                        set gotoit 0 | 
| 279 | 
                } | 
| 280 | 
                back { | 
| 281 | 
                        incr curhelp(histpos) -1 | 
| 282 | 
                        set gotoit 1 | 
| 283 | 
                } | 
| 284 | 
                forward { | 
| 285 | 
                        incr curhelp(histpos) 1 | 
| 286 | 
                        set gotoit 1 | 
| 287 | 
                } | 
| 288 | 
        } | 
| 289 | 
        if {$curhelp(histpos) + 1 >= [llength $curhelp(histlst)]} { | 
| 290 | 
                .helpwin.but.forw configure -state disabled | 
| 291 | 
        } else { | 
| 292 | 
                .helpwin.but.forw configure -state normal | 
| 293 | 
        } | 
| 294 | 
        if {$curhelp(histpos) <= 0} { | 
| 295 | 
                .helpwin.but.back configure -state disabled | 
| 296 | 
        } else { | 
| 297 | 
                .helpwin.but.back configure -state normal | 
| 298 | 
        } | 
| 299 | 
        if $gotoit { | 
| 300 | 
                eval helpgoto [lindex $curhelp(histlst) $curhelp(histpos)] | 
| 301 | 
        } | 
| 302 | 
} | 
| 303 | 
 | 
| 304 | 
proc helpsearch word {          # search for occurances of the given word | 
| 305 | 
        global curhelp helpindex | 
| 306 | 
        if {"$curhelp(search)" == {}} { | 
| 307 | 
                set curhelp(msg) "No pattern." | 
| 308 | 
                return 0 | 
| 309 | 
        } | 
| 310 | 
        set nmatches 0 | 
| 311 | 
        set cat [lindex $curhelp(catlist) 0] | 
| 312 | 
        set top [lindex $helpindex([string toupper $cat]) 0] | 
| 313 | 
        set startpos [tell $curhelp(fid)] | 
| 314 | 
        seek $curhelp(fid) $helpindex([string toupper $cat,$top]) | 
| 315 | 
        set foundmatch 0 | 
| 316 | 
        while {[gets $curhelp(fid) li] >= 0} { | 
| 317 | 
                if [regexp -nocase {^\.([A-Z][A-Z0-9]*)\.([A-Z][A-Z0-9]*)$} \ | 
| 318 | 
                                $li dummy cat top] { | 
| 319 | 
                        set foundmatch 0 | 
| 320 | 
                } elseif {! $foundmatch && \ | 
| 321 | 
                                [regexp -nocase $curhelp(search) $li]} { | 
| 322 | 
                        set foundmatch 1 | 
| 323 | 
                        if $nmatches { | 
| 324 | 
                                helphist append $cat $top | 
| 325 | 
                        } else { | 
| 326 | 
                                helphist new $cat $top | 
| 327 | 
                        } | 
| 328 | 
                        incr nmatches | 
| 329 | 
                } | 
| 330 | 
        } | 
| 331 | 
        if $nmatches { | 
| 332 | 
                set curhelp(msg) "$nmatches topic(s)." | 
| 333 | 
        } else { | 
| 334 | 
                set curhelp(msg) "Not found." | 
| 335 | 
        } | 
| 336 | 
        seek $curhelp(fid) $startpos | 
| 337 | 
        return $nmatches | 
| 338 | 
} |