+proc popup-license {} {
+ global libdir
+ set w .popup-licence
+ toplevel $w
+
+ wm title $w "License"
+
+ wm minsize $w 0 0
+
+ top-down-window $w
+
+ text $w.top.t -width 80 -height 10 -wrap word \
+ -yscrollcommand [list $w.top.s set]
+ scrollbar $w.top.s -command [list $w.top.t yview]
+
+ pack $w.top.s -side right -fill y
+ pack $w.top.t -expand yes -fill both
+
+ if {[file readable "${libdir}/LICENSE"]} {
+ set f [open "${libdir}/LICENSE" r]
+ while {[gets $f buf] != -1} {
+ $w.top.t insert end $buf
+ $w.top.t insert end "\n"
+ }
+ close $f
+ }
+ bottom-buttons $w [list {Close} [list destroy $w]] 1
+}
+
+proc about-target {} {
+ set w .about-target-w
+ global hostid
+
+ toplevel $w
+
+ wm title $w "About target"
+ place-force $w .
+ top-down-window $w
+
+ frame $w.top.a -relief ridge -border 2
+ frame $w.top.p -relief ridge -border 2
+
+ pack $w.top.a $w.top.p -side top -fill x
+
+ label $w.top.a.about -text "About"
+ label $w.top.a.irtcl -text $hostid \
+ -font -Adobe-Helvetica-Bold-R-Normal-*-240-*
+ pack $w.top.a.about $w.top.a.irtcl -side top
+
+ set i [z39 targetImplementationName]
+ label $w.top.p.in -text "Implementation name: $i"
+ set i [z39 targetImplementationId]
+ label $w.top.p.ii -text "Implementation id: $i"
+ set i [z39 targetImplementationVersion]
+ label $w.top.p.iv -text "Implementation version: $i"
+ set i [z39 options]
+ label $w.top.p.op -text "Protocol options: $i"
+
+ pack $w.top.p.in $w.top.p.ii $w.top.p.iv $w.top.p.op -side top -anchor nw
+
+ bottom-buttons $w [list {Close} [list destroy $w]] 1
+}
+
+proc about-origin-logo {n} {
+ global libdir
+ set w .about-origin-w
+ if {![winfo exists $w]} {
+ return
+ }
+ incr n
+ if {$n==10} {
+ set n 1
+ }
+ $w.top.a.logo configure -bitmap @${libdir}/bitmaps/book$n
+ after 140 [list about-origin-logo $n]
+}
+
+proc about-origin {} {
+ set w .about-origin-w
+ global libdir
+ global tk_version
+
+ if {[winfo exists $w]} {
+ destroy $w
+ }
+ toplevel $w
+
+ wm title $w "About IrTcl"
+ place-force $w .
+ top-down-window $w
+
+ frame $w.top.a -relief ridge -border 2
+ frame $w.top.p -relief ridge -border 2
+
+ pack $w.top.a $w.top.p -side top -fill x
+
+ label $w.top.a.irtcl -text "IrTcl" \
+ -font -Adobe-Helvetica-Bold-R-Normal-*-240-*
+ label $w.top.a.logo -bitmap @${libdir}/bitmaps/book1
+ pack $w.top.a.irtcl $w.top.a.logo -side left -expand yes
+
+ set i unknown
+ catch {set i [z39 implementationName]}
+ label $w.top.p.in -text "Implementation name: $i"
+ catch {set i [z39 implementationId]}
+ label $w.top.p.ii -text "Implementation id: $i"
+ catch {set i [z39 implementationVersion]}
+ label $w.top.p.iv -text "Implementation version: $i"
+ set i $tk_version
+ label $w.top.p.tk -text "Tk version: $i"
+
+ pack $w.top.p.in $w.top.p.ii $w.top.p.iv $w.top.p.tk -side top -anchor nw
+
+ about-origin-logo 1
+ bottom-buttons $w [list {Close} [list destroy $w] \
+ {License} [list popup-license]] 0
+}
+
+proc popup-marc {sno no b df} {
+ global displayFormats
+ global popupMarcdf
+
+ if {[z39.$sno type $no] != "DB"} {
+ return
+ }
+ if {$b == -1} {
+ set b 0
+ while {[winfo exists .full-marc$b]} {
+ incr b
+ }
+ }
+ set df $popupMarcdf
+ set w .full-marc$b
+ if {![winfo exists $w]} {
+ toplevelG $w
+
+ wm minsize $w 0 0
+
+ frame $w.top -relief raised -border 1
+ frame $w.bot -relief raised -border 1
+
+ pack $w.top -side top -fill both -expand yes
+ pack $w.bot -fill both
+
+ text $w.top.record -width 60 -height 5 -wrap word \
+ -yscrollcommand [list $w.top.s set]
+ scrollbar $w.top.s -command [list $w.top.record yview]
+
+ global monoFlag
+ if {! $monoFlag} {
+ $w.top.record tag configure marc-tag -foreground blue
+ $w.top.record tag configure marc-id -foreground red
+ } else {
+ $w.top.record tag configure marc-tag -foreground black
+ $w.top.record tag configure marc-id -foreground black
+ }
+ $w.top.record tag configure marc-data -foreground black
+ $w.top.record tag configure marc-head \
+ -font -Adobe-Times-Medium-R-Normal-*-180-* \
+ -background black -foreground white
+
+ $w.top.record tag configure marc-pref \
+ -font -Adobe-Times-Medium-R-Normal-*-180-* \
+ -foreground blue
+ $w.top.record tag configure marc-text \
+ -font -Adobe-Times-Medium-R-Normal-*-180-* \
+ -foreground black
+ $w.top.record tag configure marc-it \
+ -font -Adobe-Times-Medium-I-Normal-*-180-* \
+ -foreground black
+
+ pack $w.top.s -side right -fill y
+ pack $w.top.record -expand yes -fill both
+
+ bottom-buttons $w [list \
+ {Close} [list destroy $w] \
+ {Prev} {} \
+ {Next} {} \
+ {Duplicate} {}] 0
+ menubutton $w.bot.formats -text "Format" -menu $w.bot.formats.m \
+ -relief raised
+ menu $w.bot.formats.m
+ pack $w.bot.formats -expand yes -ipadx 2 -ipady 2 \
+ -padx 3 -pady 3 -side left
+ } else {
+ $w.bot.formats.m delete 0 last
+ }
+ set i 0
+ foreach f $displayFormats {
+ $w.bot.formats.m add radiobutton -label $f \
+ -variable popupMarcdf -value $i \
+ -command [list popup-marc $sno $no $b 0]
+ incr i
+ }
+ $w.top.record delete 0.0 end
+ set recordType [z39.$sno recordType $no]
+ wm title $w "$recordType record #$no"
+
+ $w.bot.2 configure -command \
+ [list popup-marc $sno [expr $no-1] $b $df]
+ $w.bot.4 configure -command \
+ [list popup-marc $sno [expr $no+1] $b $df]
+ if {$no == 1} {
+ $w.bot.2 configure -state disabled
+ } else {
+ $w.bot.2 configure -state normal
+ }
+ if {[z39.$sno type [expr $no+1]] != "DB"} {
+ $w.bot.4 configure -state disabled
+ } else {
+ $w.bot.4 configure -state normal
+ }
+ $w.bot.6 configure -command [list popup-marc $sno $no -1 0]
+ set ffunc [lindex $displayFormats $df]
+ set ffunc "display-$ffunc"
+
+ $ffunc $sno $no $w.top.record 0
+}
+
+proc update-target-hotlist {target base} {
+ global hotTargets
+
+ set olen [llength $hotTargets]
+ set i 0
+ foreach e $hotTargets {
+ if {$target == [lindex $e 0] && $base == [lindex $e 1]} {
+ set hotTargets [lreplace $hotTargets $i $i]
+ break
+ }
+ incr i
+ }
+ set hotTargets [linsert $hotTargets 0 [list $target $base]]
+ set-target-hotlist $olen
+}
+
+proc delete-target-hotlist {target} {
+ global hotTargets
+
+ set olen [llength $hotTargets]
+ set i 0
+ foreach e $hotTargets {
+ if {$target == [lindex $e 0]} {
+ set hotTargets [lreplace $hotTargets $i $i]
+ }
+ incr i
+ }
+ set-target-hotlist $olen
+}
+
+proc set-target-hotlist {olen} {
+ global hotTargets
+
+ if {$olen > 0} {
+ if {[tk4]} {
+ .top.target.m delete 7 [expr 7+$olen]
+ } else {
+ .top.target.m delete 6 [expr 6+$olen]
+ }
+ }
+ set i 1
+ foreach e $hotTargets {
+ set target [lindex $e 0]
+ set base [lindex $e 1]
+ if {$base == ""} {
+ .top.target.m add command -label "$i $target" -command \
+ [list reopen-target $target {}]
+ } else {
+ .top.target.m add command -label "$i $target - $base" -command \
+ [list reopen-target $target $base]
+ }
+ incr i
+ if {$i > 8} {
+ break
+ }
+ }
+}
+
+proc reopen-target {target base} {
+ close-target
+ open-target $target $base
+ update-target-hotlist $target $base
+}
+
+proc define-target-action {} {
+ global profile
+
+ set target [.target-define.top.target.entry get]
+ if {$target == ""} {
+ return
+ }
+ foreach n [array names profile] {
+ if {$n == $target} {
+ destroy .target-define
+ protocol-setup $n
+ return
+ }
+ }
+ set seq [lindex $profile(Default) 12]
+ dputs "seq=${seq}"
+ dputs $profile(Default)
+ set profile($target) $profile(Default)
+ set profile(Default) [lreplace $profile(Default) 12 12 [incr seq]]
+
+ protocol-setup $target
+ destroy .target-define
+}
+
+proc fail-response {target} {
+ set c [lindex [z39 failInfo] 0]
+ set m [lindex [z39 failInfo] 1]
+ close-target
+ tkerror "$m ($c)"
+}
+
+proc connect-response {target base} {
+ dputs "connect-response"
+ show-target $target $base
+ init-request
+}
+
+proc open-target {target base} {
+ global profile
+ global hostid
+ global presentChunk
+
+ z39 disconnect
+ z39 comstack [lindex $profile($target) 6]
+ z39 protocol [lindex $profile($target) 11]
+ z39 idAuthentication [lindex $profile($target) 3]
+ z39 maximumRecordSize [lindex $profile($target) 4]
+ z39 preferredMessageSize [lindex $profile($target) 5]
+ dputs "maximumRecordSize="
+ dputs [z39 maximumRecordSize]
+ dputs "preferredMessageSize="
+ dputs [z39 preferredMessageSize]
+ show-status Connecting 1 0
+ if {$base == ""} {
+ z39 databaseNames [lindex [lindex $profile($target) 7] 0]
+ } else {
+ z39 databaseNames $base
+ }
+ set x [lindex $profile($target) 13]
+ if {$x == ""} {
+ set x 2
+ }
+ z39 largeSetLowerBound $x
+
+ set x [lindex $profile($target) 14]
+ if {$x == ""} {
+ set x 0
+ }
+ z39 smallSetUpperBound $x
+
+ set x [lindex $profile($target) 15]
+ if {$x == ""} {
+ set x 0
+ }
+ z39 mediumSetPresentNumber $x
+
+ set presentChunk [lindex $profile($target) 16]
+ if {$presentChunk == ""} {
+ set presentChunk 4
+ }
+
+ z39 failback [list fail-response $target]
+ z39 callback [list connect-response $target $base]
+ update idletasks
+ set err [catch {
+ z39 connect [lindex $profile($target) 1]:[lindex $profile($target) 2]
+ } errorMessage]
+ if {$err} {
+ tkerror $errorMessage
+ show-status "Not connected" 0 {}
+ return
+ }
+ set hostid $target
+ configure-disable-e .top.target.m 0
+ configure-enable-e .top.target.m 1
+ configure-enable-e .top.target.m 2
+}
+
+proc close-target {} {
+ global hostid
+ global cancelFlag
+ global setNo
+ global setNoLast
+
+ set cancelFlag 0
+ set setNo 0
+ set setNoLast 0
+ .bot.a.set configure -text ""
+ set hostid Default
+ z39 disconnect
+ show-target {} {}
+ show-status {Not connected} 0 0
+ init-title-lines
+ show-message {}
+ configure-disable-e .top.target.m 1
+ configure-disable-e .top.target.m 2
+ if {[tk4]} {
+ .top.rset.m delete 2 last
+ } else {
+ .top.rset.m delete 1 last
+ }
+ .top.rset.m add separator
+ configure-enable-e .top.target.m 0
+}
+
+proc load-set-action {} {
+ global setNoLast
+
+ incr setNoLast
+ ir-set z39.$setNoLast z39
+
+ set fname [.load-set.top.filename.entry get]
+ destroy .load-set
+ if {$fname != ""} {
+ show-status Loading 1 {}
+ update
+ z39.$setNoLast loadFile $fname
+
+ set no [z39.$setNoLast numberOfRecordsReturned]
+ add-title-lines $setNoLast $no 1
+ }
+ set l [format "%-4d %7d" $setNoLast $no]
+ .top.rset.m add command -label $l \
+ -command [list add-title-lines $setNoLast 10000 1]
+ show-status Ready 0 {}
+}
+
+proc load-set {} {
+ set w .load-set
+ toplevel $w
+ set oldFocus [focus]
+ place-force $w .
+ top-down-window $w
+
+ frame $w.top.filename
+ pack $w.top.filename -side top -anchor e -pady 2
+
+ entry-fields $w.top {filename} \
+ {{Filename:}} \
+ {load-set-action} {destroy .load-set}
+
+ top-down-ok-cancel $w {load-set-action} 1
+ focus $oldFocus
+}
+
+proc init-request {} {
+ global cancelFlag
+
+ if {$cancelFlag} {
+ close-target
+ return
+ }
+ z39 callback {init-response}
+ show-status Initializing 1 {}
+ set err [catch {z39 init} errorMessage]
+ if {$err} {
+ tkerror $errorMessage
+ show-status Ready 0 {}
+ }
+}
+
+proc init-response {} {
+ global cancelFlag
+ global scanEnable
+
+ dputs {init-reponse}
+ if {$cancelFlag} {
+ close-target
+ return
+ }
+ if {![z39 initResult]} {
+ show-status Ready 0 1
+ set u [z39 userInformationField]
+ close-target
+ tkerror "Connection rejected by target: $u"
+ } else {
+ if {[lsearch [z39 options] scan] >= 0} {
+ set scanEnable 1
+ } else {
+ set scanEnable 0
+ }
+ show-status Ready 0 1
+ }
+}
+
+proc search-request {bflag} {
+ global setNo
+ global setNoLast
+ global profile
+ global hostid
+ global busy
+ global cancelFlag
+ global delayRequest
+ global recordSyntax
+ global elementSetNames
+
+ set target $hostid
+
+ if {[z39 connect] == ""} {
+ return
+ }
+ dputs "search-request"
+ show-message {}
+ if {!$bflag && $busy} {
+ dputs "busy: search-request ignored"
+ return
+ }
+ if {$cancelFlag} {
+ dputs "cancelFlag"
+ show-status Searching 1 0
+ set delayRequest {search-request 1}
+ return
+ }
+ set delayRequest {}
+
+ set query [index-query]
+ if {$query==""} {
+ return
+ }
+ incr setNoLast
+ set setNo $setNoLast
+ ir-set z39.$setNo z39
+
+ if {[lindex $profile($target) 10] == 1} {
+ z39.$setNo setName $setNo
+ dputs "setName=${setNo}"
+ } else {
+ z39.$setNo setName Default
+ dputs "setName=Default"
+ }
+ if {[lindex $profile($target) 8] == 1} {
+ z39.$setNo queryType rpn
+ }
+ if {[lindex $profile($target) 9] == 1} {
+ z39.$setNo queryType ccl
+ }
+ dputs Setting
+ dputs $recordSyntax
+ if {$recordSyntax == "None" } {
+ z39.$setNo preferredRecordSyntax {}
+ } else {
+ z39.$setNo preferredRecordSyntax $recordSyntax
+ }
+ if {$elementSetNames == "None" } {
+ z39.$setNo elementSetNames {}
+ z39.$setNo smallSetElementSetNames {}
+ z39.$setNo mediumSetElementSetNames {}
+ } else {
+ z39.$setNo elementSetNames $elementSetNames
+ z39.$setNo smallSetElementSetNames $elementSetNames
+ z39.$setNo mediumSetElementSetNames $elementSetNames
+ }
+ z39 callback {search-response}
+ z39.$setNo search $query
+ show-status Searching 1 0
+}
+
+proc scan-copy {y entry} {
+ set w .scan-window
+ set no [$w.top.list nearest $y]
+ dputs "no=$no"
+ .lines.$entry.e delete 0 end
+ .lines.$entry.e insert 0 [string range [$w.top.list get $no] 8 end]
+}
+
+proc scan-request {} {
+ set w .scan-window
+
+ global profile
+ global hostid
+ global scanView
+ global scanTerm
+ global curIndexEntry
+ global queryButtonsFind
+ global queryInfoFind
+ global cancelFlag
+ global delayRequest
+
+ dputs "scan-request"
+ if {$cancelFlag} {
+ dputs "cancelFlag"
+ show-status Scanning 1 0
+ set delayRequest scan-request
+ return
+ }
+ set delayRequest {}
+
+ set target $hostid
+ set scanView 0
+ set scanTerm {}
+
+ set b [lindex $queryButtonsFind $curIndexEntry]
+ set attr {}
+ foreach a [lrange [lindex $queryInfoFind [lindex $b 1]] 1 end] {
+ set attr "@attr $a $attr"
+ }
+ set title [lindex [lindex $queryInfoFind [lindex $b 1]] 0]
+ ir-scan z39.scan z39
+
+ if {![winfo exists $w]} {
+ toplevelG $w
+
+ wm minsize $w 0 0
+
+ top-down-window $w
+
+ entry $w.top.entry -relief sunken
+ pack $w.top.entry -fill x -padx 4 -pady 2
+ bind $w.top.entry <KeyRelease> [list scan-term-h $attr]
+ listbox $w.top.list -yscrollcommand [list $w.top.scroll set] \
+ -font fixed
+ scrollbar $w.top.scroll -orient vertical -border 1
+ pack $w.top.list -side left -fill both -expand yes
+ pack $w.top.scroll -side right -fill y
+ $w.top.scroll config -command [list $w.top.list yview]
+
+ bottom-buttons $w [list {Close} [list destroy $w] \
+ {Up} [list scan-up $attr] \
+ {Down} [list scan-down $attr]] 0
+ bind $w.top.list <Up> [list scan-up $attr]
+ bind $w.top.list <Down> [list scan-down $attr]
+ focus $w.top.entry
+ }
+ bind $w.top.list <Double-Button-1> [list scan-copy %y $curIndexEntry]
+ wm title $w "Scan $title"
+
+ z39 callback [list scan-response $attr 0 35]
+ z39.scan numberOfTermsRequested 5
+ z39.scan preferredPositionInResponse 1
+ z39.scan scan "${attr} 0"
+
+ show-status Scanning 1 0
+}
+
+proc scan-term-h {attr} {
+ global busy
+ global scanTerm
+
+ if {$busy} {
+ return
+ }
+ set w .scan-window
+ set nScanTerm [$w.top.entry get]
+ if {$nScanTerm == $scanTerm} {
+ return
+ }
+ set scanTerm $nScanTerm
+ z39 callback [list scan-response $attr 0 35]
+ z39.scan numberOfTermsRequested 5
+ z39.scan preferredPositionInResponse 1
+ dputs "${attr} \{${scanTerm}\}"
+ if {$scanTerm == ""} {
+ z39.scan scan "${attr} 0"
+ } else {
+ z39.scan scan "${attr} \{${scanTerm}\}"
+ }
+ show-status Scanning 1 0
+}
+
+proc scan-response {attr start toget} {
+ global cancelFlag
+ global delayRequest
+ global scanTerm
+ global scanView
+
+ set w .scan-window
+ dputs "In scan-response"
+ set m [z39.scan numberOfEntriesReturned]
+ dputs $m
+ dputs attr=$attr
+ dputs start=$start
+ dputs toget=$toget
+
+ if {![winfo exists .scan-window]} {
+ if {$cancelFlag} {
+ set cancelFlag 0
+ dputs "Handling cancel"
+ if {$delayRequest != ""} {
+ eval $delayRequest
+ }
+ return
+ }
+ show-status Ready 0 1
+ return
+ }
+ set nScanTerm [$w.top.entry get]
+ if {$nScanTerm != $scanTerm} {
+ z39 callback [list scan-response $attr 0 35]
+ z39.scan numberOfTermsRequested 5
+ z39.scan preferredPositionInResponse 1
+ set scanTerm $nScanTerm
+ dputs "${attr} \{${scanTerm}\}"
+ if {$scanTerm == ""} {
+ z39.scan scan "${attr} 0"
+ } else {
+ z39.scan scan "${attr} \{${scanTerm}\}"
+ }
+ show-status Scanning 1 0
+ return
+ }
+ set status [z39.scan scanStatus]
+ if {$status == 6} {
+ tkerror "Scan fail"
+ show-status Ready 0 1
+ set cancelFlag 0
+ return
+ }
+ if {$toget < 0} {
+ for {set i 0} {$i < $m} {incr i} {
+ set term [lindex [z39.scan scanLine $i] 1]
+ set nostr [format " %-6d" [lindex [z39.scan scanLine $i] 2]]
+ $w.top.list insert $i "$nostr $term"
+ }
+ incr scanView $m
+ $w.top.list yview $scanView
+ } else {
+ $w.top.list delete $start end
+ for {set i 0} {$i < $m} {incr i} {
+ set term [lindex [z39.scan scanLine $i] 1]
+ set nostr [format " %-6d" [lindex [z39.scan scanLine $i] 2]]
+ $w.top.list insert end "$nostr $term"
+ }
+ }
+ if {$cancelFlag} {
+ dputs "Handling cancel"
+ set cancelFlag 0
+ if {$delayRequest != ""} {
+ eval $delayRequest
+ }
+ return
+ }
+ set delayRequest {}
+ if {$toget > 0 && $m > 1 && $m < $toget} {
+ set ntoget [expr $toget - $m + 1]
+ dputs ntoget=$ntoget
+ z39 callback [list scan-response $attr [expr $start + $m - 1] $ntoget]
+ set q $term
+ dputs "down continue: $q"
+ if {$ntoget > 10} {
+ z39.scan numberOfTermsRequested 10
+ } else {
+ z39.scan numberOfTermsRequested $ntoget
+ }
+ z39.scan preferredPositionInResponse 1
+ dputs "${attr} \{$q\}"
+ z39.scan scan "${attr} \{$q\}"
+ return
+ }
+ if {$toget < 0 && $m > 1 && $m < [expr - $toget]} {
+ set ntoget [expr - $toget - $m]
+ dputs ntoget=$ntoget
+ z39 callback [list scan-response $attr 0 -$ntoget]
+ set q [string range [$w.top.list get 0] 8 end]
+ dputs "up continue: $q"
+ if {$ntoget > 10} {
+ z39.scan numberOfTermsRequested 10
+ z39.scan preferredPositionInResponse 11
+ } else {
+ z39.scan numberOfTermsRequested $ntoget
+ z39.scan preferredPositionInResponse [incr ntoget]
+ }
+ dputs "${attr} \{$q\}"
+ z39.scan scan "${attr} \{$q\}"
+ return
+ }
+ show-status Ready 0 1
+}
+
+proc scan-down {attr} {
+ global scanView
+ global cancelFlag
+ global delayRequest
+
+ dputs {scan-down}
+ if {$cancelFlag} {
+ dputs "cancelFlag"
+ show-status {Scanning down} 1 0
+ set delayRequest [list scan-down $attr]
+ return
+ }
+ set delayRequest {}
+
+ set w .scan-window
+ set scanView [expr $scanView + 5]
+ set s [$w.top.list size]
+ if {$scanView > $s} {
+ z39 callback [list scan-response $attr [expr $s - 1] 25]
+ set q [string range [$w.top.list get [expr $s - 1]] 8 end]
+ dputs "down: $q"
+ z39.scan numberOfTermsRequested 10
+ z39.scan preferredPositionInResponse 1
+ show-status Scanning 1 0
+ dputs "${attr} \{$q\}"
+ z39.scan scan "${attr} \{$q\}"
+ return
+ }
+ $w.top.list yview $scanView
+}
+
+proc scan-up {attr} {
+ global scanView
+ global cancelFlag
+ global delayRequest
+
+ dputs {scan-up}
+ if {$cancelFlag} {
+ dputs "cancelFlag"
+ show-status Scanning 1 0
+ set delayRequest [list scan-up $attr]
+ return
+ }
+ set delayRequest {}
+
+ set w .scan-window
+ set scanView [expr $scanView - 5]
+ if {$scanView < 0} {
+ z39 callback [list scan-response $attr 0 -25]
+ set q [string range [$w.top.list get 0] 8 end]
+ dputs "up: $q"
+ z39.scan numberOfTermsRequested 10
+ z39.scan preferredPositionInResponse 11
+ show-status Scanning 1 0
+ z39.scan scan "${attr} \{$q\}"
+ return
+ }
+ $w.top.list yview $scanView
+}
+
+proc search-response {} {
+ global setNo
+ global setOffset
+ global setMax
+ global cancelFlag
+ global busy
+ global delayRequest
+ global presentChunk
+
+
+ dputs "In search-response"
+ if {$cancelFlag} {
+ dputs "Handling cancel"
+ set cancelFlag 0
+ if {$delayRequest != ""} {
+ eval $delayRequest
+ }
+ return
+ }
+ set setOffset 0
+ set delayRequest {}
+ init-title-lines
+ set setMax [z39.$setNo resultCount]
+ show-status Ready 0 1
+ set status [z39.$setNo responseStatus]
+ if {[lindex $status 0] == "NSD"} {
+ z39.$setNo nextResultSetPosition 0
+ set code [lindex $status 1]
+ set msg [lindex $status 2]
+ set addinfo [lindex $status 3]
+ tkerror "NSD$code: $msg: $addinfo"
+ return
+ }
+ show-message "${setMax} hits"
+ if {$setMax == 0} {
+ return
+ }
+ set setOffset 1
+ show-status Ready 0 1
+ set l [format "%-4d %7d" $setNo $setMax]
+ .top.rset.m add command -label $l \
+ -command [list add-title-lines $setNo 10000 1]
+ if {$setMax > 20} {
+ set setMax 20
+ }
+ set no [z39.$setNo numberOfRecordsReturned]
+ dputs "Returned $no records, setOffset $setOffset"
+ add-title-lines $setNo $no $setOffset
+ set setOffset [expr $setOffset + $no]
+
+ set toGet [expr $setMax - $setOffset + 1]
+ if {$toGet > 0} {
+ if {$setOffset == 1} {
+ set toGet 1
+ } elseif {$toGet > $presentChunk} {
+ set toGet $presentChunk
+ }
+ z39 callback {present-response}
+ z39.$setNo present $setOffset $toGet
+ show-status Retrieving 1 0
+ }
+}
+
+proc present-more {number} {
+ global setNo
+ global setOffset
+ global setMax
+ global busy
+ global cancelFlag
+ global delayRequest
+ global presentChunk
+
+ dputs "present-more"
+ if {$cancelFlag} {
+ show-status Retrieving 1 0
+ set delayRequest "present-more $number"
+ return
+ }
+ set delayRequest {}
+
+ if {$setNo == 0} {
+ dputs "setNo=$setNo"
+ return
+ }
+ set setOffset [z39.$setNo nextResultSetPosition]
+ dputs "setOffest=${setOffset}"
+ dputs "setNo=${setNo}"
+ set max [z39.$setNo resultCount]
+ if {$max < $setOffset} {
+ dputs "max=$max"
+ dputs "setOffset=$setOffset"
+ show-status Ready 0 1
+ return
+ }
+ if {$number == ""} {
+ set setMax $max
+ } else {
+ incr setMax $number
+ if {$setMax > $max} {
+ set setMax $max
+ }
+ }
+ z39 callback {present-response}
+
+ set toGet [expr $setMax - $setOffset + 1]
+ if {$toGet <= 0} {
+ return
+ }
+ if {$toGet > $presentChunk} {
+ set toGet $presentChunk
+ }
+ z39.$setNo present $setOffset $toGet
+ show-status Retrieving 1 0
+}
+
+proc init-title-lines {} {
+ .data.record delete 0.0 end
+}
+
+proc add-title-lines {setno no offset} {
+ global displayFormats
+ global displayFormat
+ global setNo
+ global busy
+
+ dputs "add-title-lines offset=${offset} no=${no}"
+ if {$setno != -1} {
+ set setNo $setno
+ } else {
+ set setno $setNo
+ }
+ if {$offset == 1} {
+
+ .bot.a.set configure -text $setno
+ .data.record delete 0.0 end
+ }
+ set ffunc [lindex $displayFormats $displayFormat]
+ dputs "ffunc=$ffunc"
+ set ffunc "display-$ffunc"
+ for {set i 0} {$i < $no} {incr i} {
+ set o [expr $i + $offset]
+ set type [z39.$setno type $o]
+ if {$type == ""} {
+ dputs "no more at $o"
+ break
+ }
+ .data.record tag bind r$o <Any-Enter> {}
+ .data.record tag bind r$o <Any-Leave> {}
+ set insert0 [.data.record index insert]
+ $ffunc $setno $o .data.record 1
+ .data.record tag add r$o $insert0 insert
+ .data.record tag bind r$o <1> \
+ [list popup-marc $setno $o 0 0]
+ update idletasks
+ }
+ if {!$busy} {
+ show-status Ready 0 1
+ }
+}
+
+proc present-response {} {
+ global setNo
+ global setOffset
+ global setMax
+ global cancelFlag
+ global delayRequest
+ global presentChunk
+
+ dputs "In present-response"
+ set no [z39.$setNo numberOfRecordsReturned]
+ dputs "Returned $no records, setOffset $setOffset"
+ add-title-lines $setNo $no $setOffset
+ set setOffset [expr $setOffset + $no]
+ if {$cancelFlag} {
+ dputs "Handling cancel"
+ set cancelFlag 0
+ if {$delayRequest != ""} {
+ eval $delayRequest
+ }
+ return
+ }
+ set status [z39.$setNo responseStatus]
+ if {[lindex $status 0] == "NSD"} {
+ show-status Ready 0 1
+ set code [lindex $status 1]
+ set msg [lindex $status 2]
+ set addinfo [lindex $status 3]
+ tkerror "NSD$code: $msg: $addinfo"
+ return
+ }
+ if {$no > 0 && $setOffset <= $setMax} {
+ dputs "present-request from ${setOffset}"
+ set toGet [expr $setMax - $setOffset + 1]
+ if {$toGet > $presentChunk} {
+ set toGet $presentChunk
+ }
+ z39.$setNo present $setOffset $toGet
+ } else {
+ show-status Ready 0 1
+ }
+}
+
+proc left-cursor {w} {
+ set i [$w index insert]
+ if {$i > 0} {
+ incr i -1
+ $w icursor $i
+ }
+ dputs left
+}
+
+proc right-cursor {w} {
+ set i [$w index insert]
+ incr i
+ dputs right
+ $w icursor $i
+}
+
+proc bind-fields {list returnAction escapeAction} {
+ set max [expr [llength $list]-1]
+ for {set i 0} {$i < $max} {incr i} {
+ bind [lindex $list $i] <Return> $returnAction
+ bind [lindex $list $i] <Escape> $escapeAction
+ if {![tk4]} {
+ bind [lindex $list $i] <Tab> \
+ [list focus [lindex $list [expr $i+1]]]
+ bind [lindex $list $i] <Left> \
+ [list left-cursor [lindex $list $i]]
+ bind [lindex $list $i] <Right> \
+ [list right-cursor [lindex $list $i]]
+ }
+ }
+ bind [lindex $list $i] <Return> $returnAction
+ bind [lindex $list $i] <Escape> $escapeAction
+ if {![tk4]} {
+ bind [lindex $list $i] <Tab> [list focus [lindex $list 0]]
+ bind [lindex $list $i] <Left> [list left-cursor [lindex $list $i]]
+ bind [lindex $list $i] <Right> [list right-cursor [lindex $list $i]]
+ }
+ focus [lindex $list 0]
+}
+
+proc entry-fields {parent list tlist returnAction escapeAction} {
+ set alist {}
+ set i 0
+ foreach field $list {
+ set label ${parent}.${field}.label
+ set entry ${parent}.${field}.entry
+ label $label -text [lindex $tlist $i] -anchor e
+ entry $entry -width 32 -relief sunken
+ pack $label -side left
+ pack $entry -side right
+ lappend alist $entry
+ incr i
+ }
+ bind-fields $alist $returnAction $escapeAction
+}
+
+proc define-target-dialog {} {
+ set w .target-define
+
+ toplevel $w
+ place-force $w .
+ top-down-window $w
+ frame $w.top.target
+ pack $w.top.target \
+ -side top -anchor e -pady 2
+ entry-fields $w.top {target} \
+ {{Target:}} \
+ {define-target-action} {destroy .target-define}
+ top-down-ok-cancel $w {define-target-action} 1
+}
+
+proc protocol-setup-delete {target w} {
+ global profile
+ global settingsChanged
+
+ set a [alert "Are you sure you want to delete the target \
+definition $target ?"]
+ if {$a} {
+ destroy $w
+ unset profile($target)
+ set settingsChanged 1
+ cascade-target-list
+ delete-target-hotlist $target
+ }
+}
+
+proc protocol-setup-action {target w} {
+ global profile
+ global settingsChanged
+ global targetS
+
+ set dataBases {}
+ set settingsChanged 1
+ set len [$w.top.databases.list size]
+ for {set i 0} {$i < $len} {incr i} {
+ lappend dataBases [$w.top.databases.list get $i]
+ }
+ set wno [lindex $profile($target) 12]
+
+ set profile($target) [list [$w.top.description.entry get] \
+ [$w.top.host.entry get] \
+ [$w.top.port.entry get] \
+ [$w.top.idAuthentication.entry get] \
+ $targetS($target,MRS) \
+ $targetS($target,PMS) \
+ $targetS($target,csType) \
+ $dataBases \
+ $targetS($target,RPN) \
+ $targetS($target,CCL) \
+ $targetS($target,ResultSets) \
+ $targetS($target,protocolType) \
+ $wno \
+ $targetS($target,LSLB) \
+ $targetS($target,SSUB) \
+ $targetS($target,MSPN) \
+ $targetS($target,presentChunk) ]
+
+ cascade-target-list
+ delete-target-hotlist $target
+ dputs $profile($target)
+ destroy $w
+}
+
+proc place-force {window parent} {
+ set g [wm geometry $parent]
+
+ set p1 [string first + $g]
+ set p2 [string last + $g]
+
+ set x [expr 40+[string range $g [expr $p1 +1] [expr $p2 -1]]]
+ set y [expr 60+[string range $g [expr $p2 +1] end]]
+ wm geometry $window +${x}+${y}
+}
+
+proc add-database-action {target w} {
+ global profile
+
+ $w.top.databases.list insert end \
+ [.database-select.top.database.entry get]
+ destroy .database-select
+}
+
+proc add-database {target wp} {
+ global profile
+
+ set w .database-select
+ toplevel $w
+ set oldFocus [focus]
+
+ place-force $w $wp
+
+ top-down-window $w
+
+ frame $w.top.database
+
+ pack $w.top.database -side top -anchor e -pady 2
+
+ entry-fields $w.top {database} \
+ {{Database to add:}} \
+ [list add-database-action $target $wp] {destroy .database-select}
+
+ top-down-ok-cancel $w [list add-database-action $target $wp] 1
+ focus $oldFocus
+}
+
+proc delete-database {target w} {
+ global profile
+
+ set l {}
+ foreach i [$w.top.databases.list curselection] {
+ set b [$w.top.databases.list get $i]
+ set l "$l $b"
+ }
+ set a [alert "Are you sure you want to remove the database(s)${l}?"]
+ if {$a} {
+ foreach i [lsort -decreasing \
+ [$w.top.databases.list curselection]] {
+ $w.top.databases.list delete $i
+ }
+ }
+}
+
+proc protocol-setup {target} {
+ global profile
+ global targetS
+
+ set bno 0
+ while {[winfo exists .setup-$bno]} {
+ incr bno
+ }
+ set w .setup-$bno
+
+ toplevelG $w
+
+ wm title $w "Setup $target"
+
+ top-down-window $w
+
+ if {$target == ""} {
+ set target Default
+ }
+ dputs target
+ dputs $profile($target)
+
+ frame $w.top.description
+ frame $w.top.host
+ frame $w.top.port
+ frame $w.top.idAuthentication
+ frame $w.top.cs-type -relief ridge -border 2
+ frame $w.top.protocol -relief ridge -border 2
+ frame $w.top.query -relief ridge -border 2
+ frame $w.top.databases -relief ridge -border 2
+
+ # Maximum/preferred/idAuth ...
+ pack $w.top.description $w.top.host $w.top.port \
+ $w.top.idAuthentication -side top -anchor e -pady 2
+
+ entry-fields $w.top {description host port idAuthentication } \
+ {{Description:} {Host:} {Port:} {Id Authentication:}} \
+ [list protocol-setup-action $target $w] [list destroy $w]
+
+ foreach sub {description host port idAuthentication} {
+ dputs $sub
+ bind $w.top.$sub.entry <Control-a> [list add-database $target $w]
+ bind $w.top.$sub.entry <Control-d> [list delete-database $target $w]
+ }
+ $w.top.description.entry insert 0 [lindex $profile($target) 0]
+ $w.top.host.entry insert 0 [lindex $profile($target) 1]
+ $w.top.port.entry insert 0 [lindex $profile($target) 2]
+ $w.top.idAuthentication.entry insert 0 [lindex $profile($target) 3]
+ set targetS($target,csType) [lindex $profile($target) 6]
+ set targetS($target,RPN) [lindex $profile($target) 8]
+ set targetS($target,CCL) [lindex $profile($target) 9]
+ set targetS($target,ResultSets) [lindex $profile($target) 10]
+ set targetS($target,protocolType) [lindex $profile($target) 11]
+ if {$targetS($target,protocolType) == ""} {
+ set targetS($target,protocolType) Z39
+ }
+ set targetS($target,LSLB) [lindex $profile($target) 13]
+ set targetS($target,SSUB) [lindex $profile($target) 14]
+ set targetS($target,MSPN) [lindex $profile($target) 15]
+ set targetS($target,presentChunk) [lindex $profile($target) 16]
+ set targetS($target,MRS) [lindex $profile($target) 4]
+ set targetS($target,PMS) [lindex $profile($target) 5]
+ # Databases ....
+ pack $w.top.databases -side left -pady 2 -padx 2 -expand yes -fill both
+
+ label $w.top.databases.label -text "Databases"
+ button $w.top.databases.add -text Add \
+ -command [list add-database $target $w]
+ button $w.top.databases.delete -text Delete \
+ -command [list delete-database $target $w]
+ if {! [tk4]} {
+ listbox $w.top.databases.list -geometry 14x6 \
+ -yscrollcommand "$w.top.databases.scroll set"
+ } else {
+ listbox $w.top.databases.list -width 14 -height 5\
+ -yscrollcommand "$w.top.databases.scroll set"
+ }
+ scrollbar $w.top.databases.scroll -orient vertical -border 1
+ pack $w.top.databases.label -side top -fill x \
+ -padx 2 -pady 2
+ pack $w.top.databases.add $w.top.databases.delete -side top -fill x \
+ -padx 2 -pady 2
+ pack $w.top.databases.list -side left -fill both -expand yes \
+ -padx 2 -pady 2
+ pack $w.top.databases.scroll -side right -fill y \
+ -padx 2 -pady 2
+ $w.top.databases.scroll config -command "$w.top.databases.list yview"
+
+ foreach b [lindex $profile($target) 7] {
+ $w.top.databases.list insert end $b
+ }
+
+ # Transport ...
+ pack $w.top.cs-type -pady 2 -padx 2 -side top -fill x
+
+ label $w.top.cs-type.label -text "Transport"
+ radiobutton $w.top.cs-type.tcpip -text "TCP/IP" -anchor w \
+ -variable targetS($target,csType) -value tcpip
+ radiobutton $w.top.cs-type.mosi -text "MOSI" -anchor w\
+ -variable targetS($target,csType) -value mosi
+
+ pack $w.top.cs-type.label $w.top.cs-type.tcpip $w.top.cs-type.mosi \
+ -padx 2 -side top -fill x
+
+ # Protocol ...
+ pack $w.top.protocol -pady 2 -padx 2 -side top -fill x
+
+ label $w.top.protocol.label -text "Protocol"
+ radiobutton $w.top.protocol.z39v2 -text "Z39.50" -anchor w \
+ -variable targetS($target,protocolType) -value Z39
+ radiobutton $w.top.protocol.sr -text "SR" -anchor w \
+ -variable targetS($target,protocolType) -value SR
+
+ pack $w.top.protocol.label $w.top.protocol.z39v2 $w.top.protocol.sr \
+ -padx 2 -side top -fill x
+
+ # Query ...
+ pack $w.top.query -pady 2 -padx 2 -side top -fill x
+
+ label $w.top.query.label -text "Query support"
+ checkbutton $w.top.query.c1 -text "RPN query" -anchor w \
+ -variable targetS($target,RPN)
+ checkbutton $w.top.query.c2 -text "CCL query" -anchor w \
+ -variable targetS($target,CCL)
+ checkbutton $w.top.query.c3 -text "Result sets" -anchor w \
+ -variable targetS($target,ResultSets)
+
+ pack $w.top.query.label -side top
+ pack $w.top.query.c1 $w.top.query.c2 $w.top.query.c3 \
+ -padx 2 -side top -fill x
+
+ # Ok-cancel
+ bottom-buttons $w [list {Ok} [list protocol-setup-action $target $w] \
+ {Delete} [list protocol-setup-delete $target $w] \
+ {Advanced} [list advanced-setup $target $bno] \
+ {Cancel} [list destroy $w]] 0
+}
+
+
+proc advanced-setup {target b} {
+ global profile
+ global targetS
+
+ set w .advanced-setup-$b
+
+ toplevelG $w
+
+ wm title $w "Advanced setup $target"
+
+ top-down-window $w
+
+ if {$target == ""} {
+ set target Default
+ }
+ dputs target
+
+ frame $w.top.largeSetLowerBound
+ frame $w.top.smallSetUpperBound
+ frame $w.top.mediumSetPresentNumber
+ frame $w.top.presentChunk
+ frame $w.top.maximumRecordSize
+ frame $w.top.preferredMessageSize
+
+ pack $w.top.largeSetLowerBound $w.top.smallSetUpperBound \
+ $w.top.mediumSetPresentNumber $w.top.presentChunk \
+ $w.top.maximumRecordSize $w.top.preferredMessageSize \
+ -side top -anchor e -pady 2
+
+ entry-fields $w.top {largeSetLowerBound smallSetUpperBound \
+ mediumSetPresentNumber presentChunk maximumRecordSize \
+ preferredMessageSize} \
+ {{Large Set Lower Bound:} {Small Set Upper Bound:} \
+ {Medium Set Present Number:} {Present Chunk:} \
+ {Maximum Record Size:} {Preferred Message Size:}} \
+ [list advanced-setup-action $target $b] [list destroy $w]
+
+ $w.top.largeSetLowerBound.entry insert 0 $targetS($target,LSLB)
+ $w.top.smallSetUpperBound.entry insert 0 $targetS($target,SSUB)
+ $w.top.mediumSetPresentNumber.entry insert 0 $targetS($target,MSPN)
+ $w.top.presentChunk.entry insert 0 $targetS($target,presentChunk)
+ $w.top.maximumRecordSize.entry insert 0 $targetS($target,MRS)
+ $w.top.preferredMessageSize.entry insert 0 $targetS($target,PMS)
+
+ bottom-buttons $w [list {Ok} [list advanced-setup-action $target $b] \
+ {Cancel} [list destroy $w]] 0
+}
+
+proc advanced-setup-action {target b} {
+ set w .advanced-setup-$b
+ global targetS
+
+ set targetS($target,LSLB) [$w.top.largeSetLowerBound.entry get]
+ set targetS($target,SSUB) [$w.top.smallSetUpperBound.entry get]
+ set targetS($target,MSPN) [$w.top.mediumSetPresentNumber.entry get]
+ set targetS($target,presentChunk) [$w.top.presentChunk.entry get]
+ set targetS($target,MRS) [$w.top.maximumRecordSize.entry get]
+ set targetS($target,PMS) [$w.top.preferredMessageSize.entry get]
+
+ dputs "advanced-setup-action"
+ destroy $w
+}
+
+proc database-select-action {} {
+ set w .database-select.top
+ set b {}
+ foreach indx [$w.databases.list curselection] {
+ lappend b [$w.databases.list get $indx]
+ }
+ if {$b != ""} {
+ z39 databaseNames $b
+ }
+ destroy .database-select
+}
+
+proc database-select {} {
+ set w .database-select
+ global profile
+ global hostid
+
+ toplevel $w
+ set oldFocus [focus]
+ place-force $w .
+
+ top-down-window $w
+
+ frame $w.top.databases -relief ridge -border 2
+
+ pack $w.top.databases -side left -pady 6 -padx 6 -expand yes -fill x
+
+ label $w.top.databases.label -text "List"
+ listbox $w.top.databases.list -width 20 -height 6 \
+ -yscrollcommand "$w.top.databases.scroll set"
+ scrollbar $w.top.databases.scroll -orient vertical -border 1
+ pack $w.top.databases.label -side top -fill x \
+ -padx 2 -pady 2
+ pack $w.top.databases.list -side left -fill both -expand yes \
+ -padx 2 -pady 2
+ pack $w.top.databases.scroll -side right -fill y \
+ -padx 2 -pady 2
+ $w.top.databases.scroll config -command "$w.top.databases.list yview"
+
+ foreach b [lindex $profile($hostid) 7] {
+ $w.top.databases.list insert end $b
+ }
+ top-down-ok-cancel $w {database-select-action} 1
+ focus $oldFocus
+}
+
+proc cascade-target-list {} {
+ global profile
+
+ foreach sub [winfo children .top.target.m.clist] {
+ destroy $sub
+ }
+ .top.target.m.clist delete 0 last
+ foreach n [lsort [array names profile]] {
+ if {$n != "Default"} {
+ set nl [lindex $profile($n) 12]
+ if {[llength [lindex $profile($n) 7]] > 1} {
+ .top.target.m.clist add cascade -label $n \
+ -menu .top.target.m.clist.$nl
+ menu .top.target.m.clist.$nl
+ foreach b [lindex $profile($n) 7] {
+ .top.target.m.clist.$nl add command -label $b \
+ -command [list reopen-target $n $b]
+ }
+ } else {
+ .top.target.m.clist add command -label $n \
+ -command [list reopen-target $n {}]
+ }
+ }
+ }
+ .top.target.m.slist delete 0 last
+ foreach n [lsort [array names profile]] {
+ .top.target.m.slist add command -label $n \
+ -command [list protocol-setup $n]
+ }
+}
+
+proc query-select {i} {
+ global queryButtonsFind
+ global queryInfoFind
+ global queryButtons
+ global queryInfo
+
+ set queryInfoFind [lindex $queryInfo $i]
+ set queryButtonsFind [lindex $queryButtons $i]
+
+ index-lines .lines 1 $queryButtonsFind $queryInfoFind activate-index
+}
+
+proc query-new-action {} {
+ global queryTypes
+ global queryButtons
+ global queryInfo
+ global settingsChanged
+
+ set settingsChanged 1
+ lappend queryTypes [.query-new.top.index.entry get]
+ lappend queryButtons {}
+ lappend queryInfo {}
+
+ destroy .query-new
+ cascade-query-list
+}
+
+proc query-new {} {
+ set w .query-new
+
+ toplevel $w
+ set oldFocus [focus]
+ place-force $w .
+ top-down-window $w
+ frame $w.top.index
+ pack $w.top.index \
+ -side top -anchor e -pady 2
+ entry-fields $w.top index \
+ {{Query Name:}} \
+ query-new-action {destroy .query-new}
+ top-down-ok-cancel $w query-new-action 1
+ focus $oldFocus
+}
+
+proc query-delete-action {queryNo} {
+ global queryTypes
+ global queryButtons
+ global queryInfo
+ global settingsChanged
+
+ set settingsChanged 1
+
+ set queryTypes [lreplace $queryTypes $queryNo $queryNo]
+ set queryButtons [lreplace $queryButtons $queryNo $queryNo]
+ set queryInfo [lreplace $queryInfo $queryNo $queryNo]
+ destroy .query-delete
+ cascade-query-list
+}
+
+proc query-delete {queryNo} {
+ global queryTypes
+
+ set w .query-delete
+
+ toplevel $w
+ place-force $w .
+ top-down-window $w
+ set n [lindex $queryTypes $queryNo]
+
+ label $w.top.warning -bitmap warning
+ message $w.top.quest -text "Are you sure you want to delete the \
+query type $n ?" -aspect 300
+ pack $w.top.warning $w.top.quest -side left -expand yes -padx 10 -pady 5
+ bottom-buttons $w [list {Ok} [list query-delete-action $queryNo] \
+ {Cancel} [list destroy $w]] 1
+}
+
+proc cascade-query-list {} {
+ global queryTypes
+ set w .top.options.m.query
+
+ set i 0
+ $w.slist delete 0 last
+ foreach n $queryTypes {
+ $w.slist add command -label $n -command [list query-setup $i]
+ incr i
+ }
+
+ set i 0
+ $w.clist delete 0 last
+ foreach n $queryTypes {
+ $w.clist add command -label $n -command [list query-select $i]
+ incr i
+ }
+ set i 0
+ $w.dlist delete 0 last
+ foreach n $queryTypes {
+ $w.dlist add command -label $n -command [list query-delete $i]
+ incr i
+ }
+}
+
+proc save-geometry {} {
+ global windowGeometry
+ global hotTargets
+ global textWrap
+ global displayFormat
+ global popupMarcdf
+ global recordSyntax
+ global elementSetNames
+ global hostid
+
+ set windowGeometry(.) [wm geometry .]
+
+ if {[catch {set f [open ~/.clientrc.tcl w]}]} {
+ return
+ }
+ if {$hostid != "Default"} {
+ puts $f "set hostid $hostid"
+ set b [z39 databaseNames]
+ puts $f "set hostbase $b"
+ }
+ puts $f "set hotTargets \{ $hotTargets \}"
+ puts $f "set textWrap $textWrap"
+ puts $f "set displayFormat $displayFormat"
+ puts $f "set popupMarcdf $popupMarcdf"
+ puts $f "set recordSyntax $recordSyntax"
+ puts $f "set elementSetNames $elementSetNames"
+ foreach n [array names windowGeometry] {
+ puts -nonewline $f "set \{windowGeometry($n)\} \{"
+ puts -nonewline $f $windowGeometry($n)
+ puts $f "\}"
+ }
+ close $f
+}
+
+proc save-settings {} {
+ global profile
+ global libdir
+ global settingsChanged
+ global queryTypes
+ global queryButtons
+ global queryInfo
+
+ if {![file writable "${libdir}/clientrc.tcl"]} {
+ set a [alert "Cannot open ${libdir}/clientrc.tcl for writing. Do you \
+ wish to save clientrc.tcl in the current directory instead?"]
+ if {! $a} {
+ return
+ }
+ set f [open "clientrc.tcl" w]
+ } else {
+ set f [open "${libdir}/clientrc.tcl" w]
+ }
+ puts $f "# Setup file"
+
+ foreach n [array names profile] {
+ puts -nonewline $f "set \{profile($n)\} \{"
+ puts -nonewline $f $profile($n)
+ puts $f "\}"
+ }
+ puts -nonewline $f "set queryTypes \{"
+ puts -nonewline $f $queryTypes
+ puts $f "\}"
+
+ puts -nonewline $f "set queryButtons \{"
+ puts -nonewline $f $queryButtons
+ puts $f "\}"
+
+ puts -nonewline $f "set queryInfo \{"
+ puts -nonewline $f $queryInfo
+ puts $f "\}"
+ close $f
+ set settingsChanged 0
+}
+
+proc alert {ask} {
+ set w .alert
+
+ global alertAnswer
+
+ toplevel $w
+ set oldFocus [focus]
+ place-force $w .
+ top-down-window $w
+
+ label $w.top.warning -bitmap warning
+ message $w.top.message -text $ask -aspect 300 \
+ -font -Adobe-Times-Medium-R-Normal-*-180-*
+
+ pack $w.top.warning $w.top.message -side left -pady 5 -padx 10 -expand yes
+
+ set alertAnswer 0
+ top-down-ok-cancel $w {alert-action} 1
+ focus $oldFocus
+ return $alertAnswer
+}
+
+proc alert-action {} {
+ global alertAnswer
+ set alertAnswer 1
+ destroy .alert
+}
+
+proc exit-action {} {
+ global settingsChanged
+
+ if {$settingsChanged} {
+ set a [alert "you haven't saved your settings. Do you wish to save?"]
+ if {$a} {
+ save-settings
+ }
+ }
+ save-geometry
+ exit 0
+}
+
+proc listbuttonaction {w name h user i} {
+ $w configure -text [lindex $name 0]
+ $h [lindex $name 1] $user $i
+}
+
+proc listbuttonx {button no names handle user} {
+ if {[winfo exists $button]} {
+ $button configure -text [lindex [lindex $names $no] 0]
+ ${button}.m delete 0 last
+ } else {
+ menubutton $button -text [lindex [lindex $names $no] 0] \
+ -width 10 -menu ${button}.m -relief raised -border 1
+ menu ${button}.m
+ }
+ set i 0
+ foreach name $names {
+ ${button}.m add command -label [lindex $name 0] \
+ -command [list listbuttonaction ${button} $name \
+ $handle $user $i]
+ incr i
+ }
+}
+
+proc listbutton {button no names} {
+ menubutton $button -text [lindex $names $no] -width 10 -menu ${button}.m \
+ -relief raised -border 1
+ menu ${button}.m
+ foreach name $names {
+ ${button}.m add command -label $name \
+ -command [list ${button} configure -text $name]
+ }
+}
+
+proc listbuttonv-action {button var names i} {
+ global $var
+
+ set $var [lindex $names [expr $i+1]]
+ $button configure -text [lindex $names $i]
+}
+
+proc listbuttonv {button var names} {
+ global $var
+
+ set n "-"
+ eval "set val $$var"
+ set l [llength $names]
+ for {set i 1} {$i < $l} {incr i 2} {
+ if {$val == [lindex $names $i]} {
+ incr i -1
+ set n [lindex $names $i]
+ break
+ }
+ }
+ if {[winfo exists $button]} {
+ $button configure -text $n
+ return
+ }
+ menubutton $button -text $n -menu ${button}.m \
+ -relief raised -border 1
+ menu ${button}.m
+ for {set i 0} {$i < $l} {incr i 2} {
+ ${button}.m add command -label [lindex $names $i] \
+ -command [list listbuttonv-action $button $var $names $i]
+ }
+}
+
+proc query-add-index-action {queryNo} {
+ set w .query-setup
+
+ global queryInfoTmp
+ global queryButtonsTmp
+
+ set newI [.query-add-index.top.index.entry get]
+ lappend queryInfoTmp [list $newI {}]
+ $w.top.index.list insert end $newI
+ destroy .query-add-index
+ #destroy $w.top.lines
+ #frame $w.top.lines -relief ridge -border 2
+ index-lines $w.top.lines 0 $queryButtonsTmp $queryInfoTmp activate-e-index
+ #pack $w.top.lines -side left -pady 6 -padx 6 -fill y
+}
+
+proc query-add-line {queryNo} {
+ set w .query-setup
+
+ global queryInfoTmp
+ global queryButtonsTmp
+
+ lappend queryButtonsTmp {I 0}
+
+ #destroy $w.top.lines
+ #frame $w.top.lines -relief ridge -border 2
+ index-lines $w.top.lines 0 $queryButtonsTmp $queryInfoTmp activate-e-index
+ #pack $w.top.lines -side left -pady 6 -padx 6 -fill y
+}
+
+proc query-del-line {queryNo} {
+ set w .query-setup