home *** CD-ROM | disk | FTP | other *** search
- #
- # Hyperhelp
- # ----------------------------------------------------------------------
- # Implements a help facility using html formatted hypertext files.
- #
- # ----------------------------------------------------------------------
- # AUTHOR: Kris Raney EMAIL: kraney@spd.dsccc.com
- #
- # @(#) $Id: hyperhelp.itk,v 1.5 2002/03/16 05:26:19 mgbacke Exp $
- # ----------------------------------------------------------------------
- # Copyright (c) 1996 DSC Technologies Corporation
- # ======================================================================
- # Permission to use, copy, modify, distribute and license this software
- # and its documentation for any purpose, and without fee or written
- # agreement with DSC, is hereby granted, provided that the above copyright
- # notice appears in all copies and that both the copyright notice and
- # warranty disclaimer below appear in supporting documentation, and that
- # the names of DSC Technologies Corporation or DSC Communications
- # Corporation not be used in advertising or publicity pertaining to the
- # software without specific, written prior permission.
- #
- # DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
- # INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
- # AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
- # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL
- # DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
- # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- # SOFTWARE.
- # ======================================================================
-
- #
- # Acknowledgements:
- #
- # Special thanks go to Sam Shen(SLShen@lbl.gov), as this code is based on his
- # help.tcl code from tk inspect.
-
- #
- # Default resources.
- #
- option add *Hyperhelp.width 575 widgetDefault
- option add *Hyperhelp.height 450 widgetDefault
- option add *Hyperhelp.modality none widgetDefault
- option add *Hyperhelp.vscrollMode static widgetDefault
- option add *Hyperhelp.hscrollMode static widgetDefault
- option add *Hyperhelp.maxHistory 20 widgetDefault
-
- #
- # Usual options.
- #
- itk::usual Hyperhelp {
- keep -activebackground -activerelief -background -borderwidth -cursor \
- -foreground -highlightcolor -highlightthickness \
- -selectbackground -selectborderwidth -selectforeground \
- -textbackground
- }
-
- # ------------------------------------------------------------------
- # HYPERHELP
- # ------------------------------------------------------------------
- itcl::class iwidgets::Hyperhelp {
- inherit iwidgets::Shell
-
- constructor {args} {}
-
- itk_option define -topics topics Topics {}
- itk_option define -helpdir helpdir Directory .
- itk_option define -title title Title "Help"
- itk_option define -closecmd closeCmd CloseCmd {}
- itk_option define -maxhistory maxHistory MaxHistory 20
-
- public variable beforelink {}
- public variable afterlink {}
-
- public method showtopic {topic}
- public method followlink {link}
- public method forward {}
- public method back {}
- public method updatefeedback {n}
-
- protected method _readtopic {file {anchorpoint {}}}
- protected method _pageforward {}
- protected method _pageback {}
- protected method _lineforward {}
- protected method _lineback {}
- protected method _fill_go_menu {}
-
- protected variable _history {} ;# History list of viewed pages
- protected variable _history_ndx -1 ;# current position in history list
- protected variable _history_len 0 ;# length of history list
- protected variable _histdir -1 ;# direction in history we just came
- ;# from
- protected variable _len 0 ;# length of text to be rendered
- protected variable _file {} ;# current topic
-
- private variable _remaining 0 ;# remaining text to be rendered
- private variable _rendering 0 ;# flag - in process of rendering
- }
-
- #
- # Provide a lowercased access method for the Scrolledlistbox class.
- #
- proc ::iwidgets::hyperhelp {pathName args} {
- uplevel ::iwidgets::Hyperhelp $pathName $args
- }
-
- # ------------------------------------------------------------------
- # CONSTRUCTOR
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::constructor {args} {
- itk_option remove iwidgets::Shell::padx iwidgets::Shell::pady
-
- #
- # Create a pulldown menu
- #
- itk_component add -private menubar {
- frame $itk_interior.menu -relief raised -bd 2
- } {
- keep -background -cursor
- }
- pack $itk_component(menubar) -side top -fill x
-
- itk_component add -private topicmb {
- menubutton $itk_component(menubar).topicmb -text "Topics" \
- -menu $itk_component(menubar).topicmb.topicmenu \
- -underline 0 -padx 8 -pady 2
- } {
- keep -background -cursor -font -foreground \
- -activebackground -activeforeground
- }
- pack $itk_component(topicmb) -side left
-
- itk_component add -private topicmenu {
- menu $itk_component(topicmb).topicmenu -tearoff no
- } {
- keep -background -cursor -font -foreground \
- -activebackground -activeforeground
- }
-
- itk_component add -private navmb {
- menubutton $itk_component(menubar).navmb -text "Navigate" \
- -menu $itk_component(menubar).navmb.navmenu \
- -underline 0 -padx 8 -pady 2
- } {
- keep -background -cursor -font -foreground \
- -activebackground -activeforeground
- }
- pack $itk_component(navmb) -side left
-
- itk_component add -private navmenu {
- menu $itk_component(navmb).navmenu -tearoff no
- } {
- keep -background -cursor -font -foreground \
- -activebackground -activeforeground
- }
- set m $itk_component(navmenu)
- $m add command -label "Forward" -underline 0 -state disabled \
- -command [itcl::code $this forward] -accelerator f
- $m add command -label "Back" -underline 0 -state disabled \
- -command [itcl::code $this back] -accelerator b
- $m add cascade -label "Go" -underline 0 -menu $m.go
-
- itk_component add -private navgo {
- menu $itk_component(navmenu).go -postcommand [itcl::code $this _fill_go_menu]
- } {
- keep -background -cursor -font -foreground \
- -activebackground -activeforeground
- }
-
- #
- # Create a scrolledhtml object to display help pages
- #
- itk_component add scrtxt {
- iwidgets::scrolledhtml $itk_interior.scrtxt \
- -linkcommand "$this followlink" -feedback "$this updatefeedback"
- } {
- keep -hscrollmode -vscrollmode -background -textbackground \
- -fontname -fontsize -fixedfont -link \
- -linkhighlight -borderwidth -cursor -sbwidth -scrollmargin \
- -width -height -foreground -highlightcolor -visibleitems \
- -highlightthickness -padx -pady -activerelief \
- -relief -selectbackground -selectborderwidth \
- -selectforeground -setgrid -wrap -unknownimage
- }
- pack $itk_component(scrtxt) -fill both -expand yes
-
- #
- # Bind shortcut keys
- #
- bind $itk_component(hull) <Key-f> [itcl::code $this forward]
- bind $itk_component(hull) <Key-b> [itcl::code $this back]
- bind $itk_component(hull) <Alt-Right> [itcl::code $this forward]
- bind $itk_component(hull) <Alt-Left> [itcl::code $this back]
- bind $itk_component(hull) <Key-space> [itcl::code $this _pageforward]
- bind $itk_component(hull) <Key-Next> [itcl::code $this _pageforward]
- bind $itk_component(hull) <Key-BackSpace> [itcl::code $this _pageback]
- bind $itk_component(hull) <Key-Prior> [itcl::code $this _pageback]
- bind $itk_component(hull) <Key-Delete> [itcl::code $this _pageback]
- bind $itk_component(hull) <Key-Down> [itcl::code $this _lineforward]
- bind $itk_component(hull) <Key-Up> [itcl::code $this _lineback]
-
- wm title $itk_component(hull) "Help"
-
- eval itk_initialize $args
- if {[lsearch -exact $args -closecmd] == -1} {
- configure -closecmd [itcl::code $this deactivate]
- }
- }
-
- # ------------------------------------------------------------------
- # OPTIONS
- # ------------------------------------------------------------------
-
- # ------------------------------------------------------------------
- # OPTION: -topics
- #
- # Specifies the topics to display on the menu. For each topic, there should
- # be a file named <helpdir>/<topic>.html
- # ------------------------------------------------------------------
- itcl::configbody iwidgets::Hyperhelp::topics {
- set m $itk_component(topicmenu)
- $m delete 0 last
- foreach topic $itk_option(-topics) {
- if {[lindex $topic 1] == {} } {
- $m add radiobutton -variable topic \
- -value $topic \
- -label $topic \
- -command [list $this showtopic $topic]
- } else {
- if {[string index [file dirname [lindex $topic 1]] 0] != "/" && \
- [string index [file dirname [lindex $topic 1]] 0] != "~"} {
- set link $itk_option(-helpdir)/[lindex $topic 1]
- } else {
- set link [lindex $topic 1]
- }
- $m add radiobutton -variable topic \
- -value [lindex $topic 0] \
- -label [lindex $topic 0] \
- -command [list $this followlink $link]
- }
- }
- $m add separator
- $m add command -label "Close Help" -underline 0 \
- -command $itk_option(-closecmd)
- }
-
- # ------------------------------------------------------------------
- # OPTION: -title
- #
- # Specify the window title.
- # ------------------------------------------------------------------
- itcl::configbody iwidgets::Hyperhelp::title {
- wm title $itk_component(hull) $itk_option(-title)
- }
-
- # ------------------------------------------------------------------
- # OPTION: -helpdir
- #
- # Set location of help files
- # ------------------------------------------------------------------
- itcl::configbody iwidgets::Hyperhelp::helpdir {
- if {[file pathtype $itk_option(-helpdir)] == "relative"} {
- configure -helpdir [file join [pwd] $itk_option(-helpdir)]
- } else {
- set _history {}
- set _history_len 0
- set _history_ndx -1
- $itk_component(navmenu) entryconfig 0 -state disabled
- $itk_component(navmenu) entryconfig 1 -state disabled
- configure -topics $itk_option(-topics)
- }
- }
-
- # ------------------------------------------------------------------
- # OPTION: -closecmd
- #
- # Specify the command to execute when close is selected from the menu
- # ------------------------------------------------------------------
- itcl::configbody iwidgets::Hyperhelp::closecmd {
- $itk_component(topicmenu) entryconfigure last -command $itk_option(-closecmd)
- }
-
- # ------------------------------------------------------------------
- # METHODS
- # ------------------------------------------------------------------
-
- # ------------------------------------------------------------------
- # METHOD: showtopic topic
- #
- # render text of help topic <topic>. The text is expected to be found in
- # <helpdir>/<topic>.html
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::showtopic {topic} {
- if ![regexp {(.*)#(.*)} $topic dummy topicname anchorpart] {
- set topicname $topic
- set anchorpart {}
- }
- if {$topicname == ""} {
- set topicname $_file
- set filepath $_file
- } else {
- set filepath $itk_option(-helpdir)/$topicname.html
- }
- if {[incr _history_ndx] < $itk_option(-maxhistory)} {
- set _history [lrange $_history 0 [expr {$_history_ndx - 1}]]
- set _history_len [expr {$_history_ndx + 1}]
- } else {
- incr _history_ndx -1
- set _history [lrange $_history 1 $_history_ndx]
- set _history_len [expr {$_history_ndx + 1}]
- }
- lappend _history [list $topicname $filepath $anchorpart]
- _readtopic $filepath $anchorpart
- }
-
- # ------------------------------------------------------------------
- # METHOD: followlink link
- #
- # Callback for click on a link. Shows new topic.
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::followlink {link} {
- if {[string compare $beforelink ""] != 0} {
- eval $beforelink $link
- }
- if ![regexp {(.*)#(.*)} $link dummy filepart anchorpart] {
- set filepart $link
- set anchorpart {}
- }
- if {$filepart != "" && [string index [file dirname $filepart] 0] != "/" && \
- [string index [file dirname $filepart] 0] != "~"} {
- set filepart [$itk_component(scrtxt) pwd]/$filepart
- set hfile $filepart
- } else {
- set hfile $_file
- }
- incr _history_ndx
- set _history [lrange $_history 0 [expr {$_history_ndx - 1}]]
- set _history_len [expr {$_history_ndx + 1}]
- lappend _history [list [file rootname [file tail $hfile]] $hfile $anchorpart]
- set ret [_readtopic $filepart $anchorpart]
- if {[string compare $afterlink ""] != 0} {
- eval $afterlink $link
- }
- return $ret
- }
-
- # ------------------------------------------------------------------
- # METHOD: forward
- #
- # Show topic one forward in history list
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::forward {} {
- if {$_rendering || ($_history_ndx+1) >= $_history_len} return
- incr _history_ndx
- eval _readtopic [lrange [lindex $_history $_history_ndx] 1 end]
- }
-
- # ------------------------------------------------------------------
- # METHOD: back
- #
- # Show topic one back in history list
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::back {} {
- if {$_rendering || $_history_ndx <= 0} return
- incr _history_ndx -1
- set _histdir 1
- eval _readtopic [lrange [lindex $_history $_history_ndx] 1 end]
- }
-
- # ------------------------------------------------------------------
- # METHOD: updatefeedback remaining
- #
- # Callback from text to update feedback widget
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::updatefeedback {n} {
- if {($_remaining - $n) > .1*$_len} {
- [$itk_interior.feedbackshell childsite].helpfeedback step [expr {$_remaining - $n}]
- update idletasks
- set _remaining $n
- }
- }
-
- # ------------------------------------------------------------------
- # PRIVATE METHOD: _readtopic
- #
- # Read in file, render it in text area, and jump to anchorpoint
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::_readtopic {file {anchorpoint {}}} {
- if {$file != ""} {
- if {[string compare $file $_file] != 0} {
- if {[catch {set f [open $file r]} err]} {
- incr _history_ndx $_histdir
- set _history_len [expr {$_history_ndx + 1}]
- set _histdir -1
- set m $itk_component(navmenu)
- if {($_history_ndx+1) < $_history_len} {
- $m entryconfig 0 -state normal
- } else {
- $m entryconfig 0 -state disabled
- }
- if {$_history_ndx > 0} {
- $m entryconfig 1 -state normal
- } else {
- $m entryconfig 1 -state disabled
- }
- return
- }
- set _file $file
- set txt [read $f]
- iwidgets::shell $itk_interior.feedbackshell -title \
- "Rendering HTML" -padx 1 -pady 1
- iwidgets::Feedback [$itk_interior.feedbackshell \
- childsite].helpfeedback \
- -steps [set _len [string length $txt]] \
- -labeltext "Rendering HTML" -labelpos n
- pack [$itk_interior.feedbackshell childsite].helpfeedback
- $itk_interior.feedbackshell center $itk_interior
- $itk_interior.feedbackshell activate
- set _remaining $_len
- set _rendering 1
- if {[catch {$itk_component(scrtxt) render $txt [file dirname \
- $file]} err]} {
- if [regexp "</pre>" $err] {
- $itk_component(scrtxt) render "<tt>$err</tt>"
- } else {
- $itk_component(scrtxt) render "<pre>$err</pre>"
- }
- }
- wm title $itk_component(hull) "Help: $file"
- itcl::delete object [$itk_interior.feedbackshell \
- childsite].helpfeedback
- itcl::delete object $itk_interior.feedbackshell
- set _rendering 0
- }
- }
- set m $itk_component(navmenu)
- if {($_history_ndx+1) < $_history_len} {
- $m entryconfig 0 -state normal
- } else {
- $m entryconfig 0 -state disabled
- }
- if {$_history_ndx > 0} {
- $m entryconfig 1 -state normal
- } else {
- $m entryconfig 1 -state disabled
- }
- if {$anchorpoint != {}} {
- $itk_component(scrtxt) import -link #$anchorpoint
- } else {
- $itk_component(scrtxt) import -link #
- }
- set _histdir -1
- }
-
- # ------------------------------------------------------------------
- # PRIVATE METHOD: _fill_go_menu
- #
- # update go submenu with current history
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::_fill_go_menu {} {
- set m $itk_component(navgo)
- catch {$m delete 0 last}
- for {set i [expr {$_history_len - 1}]} {$i >= 0} {incr i -1} {
- set topic [lindex [lindex $_history $i] 0]
- set filepath [lindex [lindex $_history $i] 1]
- set anchor [lindex [lindex $_history $i] 2]
- $m add command -label $topic \
- -command [list $this followlink $filepath#$anchor]
- }
- }
-
- # ------------------------------------------------------------------
- # PRIVATE METHOD: _pageforward
- #
- # Callback for page forward shortcut key
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::_pageforward {} {
- $itk_component(scrtxt) yview scroll 1 pages
- }
-
- # ------------------------------------------------------------------
- # PRIVATE METHOD: _pageback
- #
- # Callback for page back shortcut key
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::_pageback {} {
- $itk_component(scrtxt) yview scroll -1 pages
- }
-
- # ------------------------------------------------------------------
- # PRIVATE METHOD: _lineforward
- #
- # Callback for line forward shortcut key
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::_lineforward {} {
- $itk_component(scrtxt) yview scroll 1 units
- }
-
- # ------------------------------------------------------------------
- # PRIVATE METHOD: _lineback
- #
- # Callback for line back shortcut key
- # ------------------------------------------------------------------
- itcl::body iwidgets::Hyperhelp::_lineback {} {
- $itk_component(scrtxt) yview scroll -1 units
- }
-