File:  [LON-CAPA] / capa / capa51 / GUITools / gradesubjective.tcl
Revision 1.10: download - view: text, annotated - select for diffs
Wed Mar 22 21:08:02 2000 UTC (24 years, 4 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- Lots of little changes

    1: set gMaxSet 99
    2: 
    3: proc gradeSubjective {} {
    4:     global gSubj
    5: 
    6:     if { [winfo exists .gradeSubjective] } { return }
    7:     set var [tk_getOpenFile -title "Please select a capa.config file" -filetypes \
    8: 		 { { {Capa Config} {capa.config} } }]
    9:     
   10:     if { $var != "" } {
   11: 	set gSubj(dir) [file dirname $var]
   12: 	cd $gSubj(dir)
   13:     } else {
   14: 	return
   15:     }
   16:     parseCapaConfig
   17:     if { "" == [set gSubj(set) [getOneSet {} $gSubj(dir)]] } return
   18:     if { "" == [set gSubj(quest) [getString {} "Which question?"]] } return
   19:     set fileid [open "records/set$gSubj(set).db" r]
   20:     gets $fileid aline
   21:     gets $fileid aline
   22:     set gSubj(max) [lindex [split $aline {}] [expr $gSubj(quest) - 1]]
   23:     set gSubj(keywords) ""
   24:     createGradeSubjWindow
   25: }
   26: 
   27: proc createGradeSubjWindow {} {
   28:     global gSubj
   29: 
   30:     set gradSubj [toplevel .gradesubjective]
   31:     wm protocol $gradSubj WM_DELETE_WINDOW "subjDone"
   32: 
   33:     set info [frame $gradSubj.info]
   34:     set grade [frame $gradSubj.grade]
   35:     set keyword [frame $gradSubj.keyword]
   36:     set gSubj(pictFrame) [set picts [frame $gradSubj.picts -borderwidth 4 -relief groove]]
   37:     pack $info $grade $keyword -side top
   38: 
   39:     set msg [frame $info.msg]
   40:     set id [frame $info.id]
   41:     pack $msg $id -side left
   42:     
   43: #    set gSubj(msg) [text $msg.text -width 40 -height 8 -yscrollcommand "$msg.scroll set"]
   44: #    scrollbar $msg.scroll -command "$msg.text yview"
   45: #    pack $gSubj(msg) $msg.scroll -side left
   46: #    pack configure $msg.scroll -fill y
   47: #    $gSubj(msg) tag configure error -foreground red
   48: #    $gSubj(msg) tag configure info -foreground #006c00
   49: 
   50:     set msglist [frame $msg.msglist]
   51:     set msgbutton [frame $msg.msgbutton]
   52:     pack $msglist $msgbutton -side top
   53:     pack configure $msgbutton -anchor w
   54: 
   55:     set gSubj(responseList) [listbox $msglist.list -width 40 -height 5 \
   56: 				 -yscrollcommand "$msglist.scroll set"]
   57:     scrollbar $msglist.scroll -command "$msglist.list yview"
   58:     pack $gSubj(responseList) $msglist.scroll -side left
   59:     pack configure $msglist.scroll -fill y
   60:     
   61:     set gSubj(numresponse) 0
   62: 
   63:     button $msgbutton.send -text Send -command subjSendResponse
   64:     button $msgbutton.new -text New -command subjNewResponse
   65:     button $msgbutton.delete -text Delete -command subjDeleteResponse
   66:     button $msgbutton.view -text View -command subjViewResponse
   67:     button $msgbutton.edit -text Edit -command subjEditResponse
   68:     pack $msgbutton.send $msgbutton.new $msgbutton.delete $msgbutton.view \
   69: 	$msgbutton.edit -side left
   70: 
   71:     set idlist [frame $id.idlist]
   72:     set idbutton [frame $id.idbutton]
   73:     pack $idlist $idbutton -side top
   74:     pack configure $idbutton -anchor w
   75: 
   76:     set gSubj(idlist) [listbox $idlist.list -width 34 -height 5 \
   77: 			   -yscrollcommand "$idlist.scroll set"]
   78:     scrollbar $idlist.scroll -command "$idlist.list yview"
   79:     pack $idlist.list $idlist.scroll -side left
   80:     pack configure $idlist.scroll -fill y
   81: 
   82:     button $idbutton.delete -text Delete -command subjDeleteId
   83:     frame $idbutton.spacer -width 30
   84:     label $idbutton.l1 -text "\# Words:"
   85:     label $idbutton.words -textvariable gSubj(numwords)
   86:     pack $idbutton.delete $idbutton.spacer $idbutton.l1 $idbutton.words -side left 
   87:     
   88:     set response [frame $grade.response]
   89:     pack $response 
   90: 
   91:     set scoreandcom [toplevel $gradSubj.scoreandcom]
   92:     wm title $scoreandcom "Control Panel"  
   93:     wm protocol $scoreandcom WM_DELETE_WINDOW "subjDone"
   94: 
   95:     set score [frame $scoreandcom.score]
   96:     set command [frame $scoreandcom.command]
   97:     set morebut [frame $scoreandcom.morebut]
   98:     set stat [frame $scoreandcom.stat]
   99:     pack $score $command $morebut $stat -side top
  100: 
  101:     set command1 [frame $command.command1]
  102:     set command2 [frame $command.command2]
  103:     pack $command1 $command2 -side left
  104: 
  105:     set top [frame $response.top]
  106:     set bot [frame $response.bot]
  107:     pack $top $bot -side top
  108:     pack configure $bot -expand 0 -fill x
  109: 
  110:     set gSubj(response) [text $top.response -width 80 -height 21 \
  111: 			     -yscrollcommand "$top.scroll set" \
  112: 			     -xscrollcommand "$bot.scroll set"]
  113:     scrollbar $top.scroll -command "$top.response yview"
  114:     pack $gSubj(response) $top.scroll -side left
  115:     pack configure $top.scroll -fill y
  116: 
  117:     scrollbar $bot.scroll -orient h -command "$top.response xview"
  118:     pack $bot.scroll 
  119:     pack configure $bot.scroll -expand 0 -fill x
  120: 
  121:     set left [frame $keyword.left]
  122:     set left2 [frame $keyword.left2]
  123:     set right [frame $keyword.right]
  124:     pack $left $left2 $right -side left
  125: 
  126:     set gSubj(keyword) [text $right.keyword -width 60 -height 5 \
  127: 			    -yscrollcommand "$right.scroll set" ]
  128:     scrollbar $right.scroll -command "$right.response yview"
  129:     pack $gSubj(keyword) $right.scroll -side left
  130:     pack configure $right.scroll -fill y
  131: 
  132:     bindtags $gSubj(keyword) "$gSubj(keyword) all"
  133:     bind $gSubj(keyword) <1> "[bind Text <1>][bind Text <Double-1>]"
  134: 
  135:     button $left.add -command "subjAddKeyword" -text "Add"
  136:     button $left2.addsp -command "subjAddKeywordSpelling" -text "Add Sp"
  137:     button $left.delete -command "subjDeleteKeyword" -text "Delete"
  138:     button $left2.see -command "subjSeeKeyword" -text "See Sp"
  139:     pack $left.add $left2.addsp $left.delete $left2.see -side top
  140: 
  141:     wm geometry $gradSubj "-10+0"
  142: 
  143:     set score0 [frame $score.score0]
  144:     set score1 [frame $score.score1]
  145:     pack $score0 $score1 -side top
  146: 
  147:     for {set i 0} {$i < 10 } { incr i } {
  148: 	set parent [eval set "score[expr $i/5]"]
  149: 	set a [frame $parent.score$i -relief sunken -borderwidth 1]
  150: 	if { $gSubj(max) < $i} {
  151: 	    radiobutton $a.score$i -text $i -variable gSubj(score) \
  152: 		-value $i -state disabled
  153: 	} else {
  154: 	    radiobutton $a.score$i -text $i -variable gSubj(score) -value $i
  155: 	}
  156: 	pack $parent.score$i $a.score$i -side left
  157:     }
  158: 
  159:     set buttonwidth 8
  160:     set gSubj(wrap) 1;set gSubj(pict) 0
  161:     button $command1.setnext -text "Grade&Next" -command "subjSet;subjNext" \
  162: 	-width $buttonwidth
  163:     button $command2.set -text "Grade" -command subjSet -width $buttonwidth
  164:     frame  $command1.space1 -height 30
  165:     frame  $command2.space2 -height 30
  166:     frame  $command2.space22 -height 5
  167:     button $command1.next -text "Next" -command subjNext -width $buttonwidth
  168:     button $command1.prev -text "Prev" -command subjPrev -width $buttonwidth
  169:     button $command1.goto -text "GoTo" -command subjGoto -width $buttonwidth
  170:     button $command1.exit -text "Exit" -command subjDone -width $buttonwidth
  171:     button $command2.findid -text "Find ID" -command subjFindId -width $buttonwidth
  172:     button $command2.addid -text "Add ID" -command subjAddId -width $buttonwidth
  173:     button $command2.findname -text "Find Name" -command subjFindName -width $buttonwidth
  174:     checkbutton $command2.wrap -text wrap -command subjWrap -variable gSubj(wrap)
  175:     checkbutton $command2.pict -text pict -command subjPict -variable gSubj(pict)
  176:     checkbutton $command1.done -text graded -variable gSubj(donestat) -state disabled
  177:     pack $command1.setnext $command2.set $command1.space1 $command2.space2 \
  178: 	$command1.next $command1.prev $command2.findid \
  179: 	$command2.addid $command2.findname $command1.goto $command1.exit \
  180:         $command2.wrap $command2.pict $command1.done $command2.space22
  181: 
  182:     button $morebut.print -text "Print Response" -command subjPrint \
  183: 	-width [expr $buttonwidth*2]
  184:     pack $morebut.print
  185: 
  186:     set gSubj(done) 0
  187:     set gSubj(togo) 0
  188:     set gSubj(secAvg) 0.0
  189:     set gSubj(sec) 0
  190:     set gSubj(pause) 0
  191:     label $stat.done -text Done:
  192:     label $stat.donenum -textvariable gSubj(done) -width 4
  193:     label $stat.togo -text "To Go:"
  194:     label $stat.togonum -textvariable gSubj(togo) -width 4
  195:     label $stat.sec -text Sec:
  196:     label $stat.secnum -textvariable gSubj(sec) -width 4
  197:     label $stat.avgsec -text AvgSec:
  198:     label $stat.avgsecnum -textvariable gSubj(avgsec) -width 4
  199:     checkbutton $stat.pause -variable gSubj(pause) -text "Pause" -command subjPause
  200:     pack $stat.done $stat.donenum $stat.togo $stat.togonum -side left 
  201:     #not packed
  202:     #$stat.sec $stat.secnum $stat.avgsec $stat.avgsecnum $stat.pause
  203: 
  204:     set gSubj(canvas) [canvas $picts.canvas -height 220 \
  205: 			   -xscrollcommand "$picts.scroll set"]
  206:     scrollbar $picts.scroll -orient h -command "$picts.canvas xview"
  207:     pack  $picts.scroll $gSubj(canvas) -fill x
  208:     subjInit
  209: }
  210: 
  211: proc subjWrap {} {
  212:     global gSubj 
  213:     if { $gSubj(wrap) } {
  214: 	$gSubj(response) configure -wrap char
  215:     } else {
  216: 	$gSubj(response) configure -wrap none
  217:     }
  218: }
  219: 
  220: proc updateSecCount {} {
  221:     global gSubj
  222:     
  223:     if { [catch {set gSubj(pause)}] } { return }
  224:     if { !$gSubj(pause) } {set gSubj(sec) [expr {[clock seconds] - $gSubj(seconds)}]}
  225:     after 300 updateSecCount
  226: }
  227: 
  228: proc subjCheckForNew {} {
  229:     global gSubj
  230:  
  231:     foreach file [glob ?????????] {
  232: 	if { [lsearch $gSubj(stunums) $file] == -1 } { lappend gSubj(stunums) $file }
  233:     }
  234:     set gSubj(togo) [expr [llength $gSubj(stunums)]-$gSubj(done)]
  235: }
  236: 
  237: proc checkGSubj {} {
  238:     global gSubj
  239:     if {[catch {set gSubj(stunums)}]} {
  240: 	cd [file join $gSubj(dir) records set$gSubj(set) problem$gSubj(quest)]
  241: 	set gSubj(stunums) [lsort -dictionary [glob *]]
  242: 	if { [set num [lsearch $gSubj(stunums) gradingstatus]] != -1} {
  243: 	    set gSubj(stunums) [lreplace $gSubj(stunums) $num $num]
  244: 	}
  245: 	cd $gSubj(dir)
  246:     }
  247:     if {[catch {set gSubj(current)}]} {set gSubj(current) -1}
  248:     if {[catch {set gSubj(totalsec)}]} {set gSubj(totalsec) 0}
  249:     if {[catch {set gSubj(seconds)}]} {set gSubj(seconds) [clock seconds]}
  250:     if {[catch {set gSubj(togo)}]} {set gSubj(togo) [llength $gSubj(stunums)]}
  251:     if {[catch {set gSubj(allstunum)}] || 
  252: 	[catch {set gSubj(allname)}] || 
  253: 	[catch {set gSubj(allemail)}] } {
  254: 	subjInitAllLists
  255:     }
  256: }
  257: 
  258: proc subjRestore {} {
  259:     global gSubj
  260:     source gradingstatus
  261:     subjCheckForNew
  262:     set gSubj(seconds) [expr {[clock seconds] - $gSubj(sec)}]
  263:     cd $gSubj(dir)
  264:     if { [catch {incr gSubj(current) -1}]} { set gSubj(current) -1 }
  265:     if { $gSubj(redoalllists) } { subjInitAllLists; set gSubj(redoalllists) 0 }
  266:     checkGSubj
  267:     subjIndexResponse
  268:     subjNext
  269: }
  270: 
  271: proc subjSave {} {
  272:     global gSubj
  273:     set file [file join $gSubj(dir) records set$gSubj(set) \
  274: 		  problem$gSubj(quest) gradingstatus]
  275:     set fileId [open $file w]
  276:     puts $fileId "array set gSubj \{[array get gSubj]\}"
  277:     close $fileId
  278: }
  279: 
  280: proc subjDone {} {
  281:     global gSubj
  282:     if { [catch {subjSave}] } {
  283: 	displayMessage "Unable to save."
  284:     }
  285:     unset gSubj
  286:     destroy .gradesubjective
  287: }
  288: 
  289: proc subjInitAllLists {} {
  290:     global gSubj
  291:     set i 0
  292:     catch {unset gSubj(allstunum)}
  293:     catch {unset gSubj(allname)}
  294:     catch {unset gSubj(allemail)}
  295:     set fileId [open classl r]
  296:     while { 1 } {
  297: 	incr i
  298: 	set aline [gets $fileId]
  299: 	if { [eof $fileId]} {break}
  300: 	# skip blank lines
  301: 	if { [string trim $aline] == "" } { continue }
  302: 	lappend gSubj(allstunum) [string toupper [string range $aline 14 22]]
  303: 	#lappend gSubj(allname) [string toupper [string range $aline 24 59]]
  304: 	lappend gSubj(allname) [string range $aline 24 59]
  305: 	lappend gSubj(allemail) [string range $aline 60 99]
  306:     }
  307: }
  308: 
  309: proc subjInit {} {
  310:     global gSubj
  311:     
  312:     set dir [file join $gSubj(dir) records set$gSubj(set) problem$gSubj(quest)]
  313:     cd $dir
  314:     set gSubj(redoalllists) 0
  315:     if { [file exists gradingstatus] } { subjRestore } else {
  316: 	set gSubj(stunums) [lsort -dictionary [glob *]]
  317: 	cd $gSubj(dir)
  318: 	set gSubj(current) -1
  319: 	set gSubj(totalsec) 0
  320: 	set gSubj(seconds) [clock seconds]
  321: 	subjInitAllLists
  322: 	set gSubj(togo) [llength $gSubj(stunums)]
  323: 	subjNext
  324:     }
  325:     subjUpdateKeywords
  326:     after 300 updateSecCount
  327: }
  328: 
  329: #FIXME check Ids when adding them to the list of ids
  330: proc checkId { id } {
  331:     global gSubj
  332:     set score [getScore $gSubj(set) $gSubj(quest) $id]
  333:     if { $score == "-" || $score == "0" } { return 1 }
  334:     return 0
  335: }
  336: 
  337: proc subjPause {} {
  338:     global gSubj
  339:     if { !$gSubj(pause) } { set gSubj(seconds) [expr {[clock seconds] - $gSubj(sec)}] }
  340: }
  341: 
  342: proc subjStatusUpdate {} {
  343:     global gSubj
  344:     
  345:     set gSubj(done) [llength [array names gSubj "done.*.score"]]
  346:     set total [llength $gSubj(stunums)]
  347:     set gSubj(togo) [expr $total-$gSubj(done)]
  348:     incr gSubj(totalsec) [expr {[clock seconds] - $gSubj(seconds)}]
  349:     set gSubj(avgsec) [format %4.1f [expr $gSubj(totalsec)/double($gSubj(done))]]
  350: #    puts $gSubj(avgsec)
  351:     set gSubj(seconds) [clock seconds]
  352: }
  353: 
  354: proc subjSet {} {
  355:     global gSubj
  356: 
  357: #    if {$gSubj(togo) == 0} { return }
  358:     if {$gSubj(score) == "" } { subjMessage "Please select a score." error; return }
  359:     set idlist [subjGetIdList]
  360:     foreach id $idlist {
  361: 	setScore $gSubj(set) $gSubj(quest) $id $gSubj(score)
  362:     }
  363:     set id [lindex $gSubj(stunums) $gSubj(current)]
  364:     set gSubj(done.$id.idlist) $idlist
  365:     set gSubj(done.$id.score) $gSubj(score)
  366:     set gSubj(donestat) 1
  367:     subjStatusUpdate
  368:     subjSave
  369: }
  370: 
  371: proc subjNext {} {
  372:     global gSubj
  373: 
  374:     set gSubj(score) ""
  375:     set gSubj(pict) 0
  376:     subjPict
  377:     incr gSubj(current)
  378:     if { [llength $gSubj(stunums)] < $gSubj(current) } { incr gSubj(current) -1 }
  379:     set id [lindex $gSubj(stunums) $gSubj(current)]
  380: 
  381:     $gSubj(response) delete 0.0 end
  382:     $gSubj(idlist) delete 0 end
  383: 
  384:     if { $id != "" } { 
  385: 	set file [file join $gSubj(dir) records set$gSubj(set) problem$gSubj(quest) $id]
  386: 	set fileId [open $file "r"]
  387: 	$gSubj(response) insert 0.0 [read $fileId [file size $file]]
  388: 	close $fileId
  389: 	subjInsertIds $id
  390:     }
  391: 
  392:     append words [string trim [$gSubj(response) get 0.0 end-1c]] " "
  393:     set ws [format " \t\n"]
  394:     set gSubj(numwords) [regsub -all -- \[$ws\]+  $words {} b]
  395:     wm title .gradesubjective "Grading Subjective, Set $gSubj(set), Prob $gSubj(quest), $id"
  396:     if { [catch {set gSubj(score) $gSubj(done.$id.score)}] } {
  397: 	set gSubj(score) ""
  398: 	set gSubj(donestat) 0
  399: 	update idletasks
  400: 	subjFindIds
  401:     } else {
  402: 	set gSubj(donestat) 1
  403: 	subjInsertIds $gSubj(done.$id.idlist)
  404: 	update idletasks
  405:     }
  406:     subjUpdateResponse
  407:     subjPicts
  408: }
  409: 
  410: proc subjFindIds1 {} {
  411:     global gSubj
  412: 
  413:     set text [$gSubj(response) get 0.0 end]
  414:     set result ""
  415:     foreach id $gSubj(allstunum) {
  416: 	if { [regexp -nocase -- $id $text] } {
  417: 	    lappend result $id
  418: 	}
  419:     }
  420:     return $result
  421: }
  422: 
  423: proc subjFindIds2 {} {
  424:     global gSubj
  425: 
  426:     set text [string toupper [$gSubj(response) get 0.0 end]]
  427:     set result ""
  428:     if { [catch {lsearch $text a}] } { 
  429: 	#puts badlist
  430: 	return subjFindIds1 
  431:     } else {
  432: 	foreach id $gSubj(allstunum) {
  433: 	    if { [lsearch -glob $text *$id*] != -1 } {
  434: 		lappend result $id
  435: 	    }
  436: 	}
  437:     }
  438:     return $result
  439: }
  440: 
  441: proc subjFindIds3 {} {
  442:     global gSubj
  443: 
  444:     set text [string toupper [$gSubj(response) get 0.0 end]]
  445:     set text [split $text "{}!@\#\$%^&*()_-+=|\\,.<>/?'\";:`~ \n\t"]
  446:     set result ""
  447:     foreach word $text {
  448: 	if { [lsearch -exact $gSubj(allstunum) $word] != -1 } {
  449: 	    lappend result $word
  450: 	}
  451:     }
  452:     return $result
  453: }
  454: 
  455: proc subjFindIds4 {} {
  456:     global gSubj
  457: 
  458:     set text [string toupper [$gSubj(response) get 0.0 end]]
  459:     set text [split $text "{}!@\#\$%^&*()_-+=|\\,.<>/?'\";:`~ \n\t"]
  460:     set result ""
  461:     foreach id $gSubj(allstunum) {
  462: 	if { [lsearch -exact $text $id] != -1 } {
  463: 	    lappend result $id
  464: 	}
  465:     }
  466:     return $result
  467: }
  468: 
  469: proc subjFindId {} {
  470:     global gSubj
  471:     puts "4:[time {subjInsertIds [set ids [subjFindIds4]]} ]\t:[llength $ids]"
  472:     subjPicts
  473: }
  474: 
  475: proc subjFindIds {} {
  476:     global gSubj
  477: #    puts "4:[time {subjInsertIds [set ids [subjFindIds4]]} ]\t:[llength $ids]"
  478:     subjInsertIds [set ids [subjFindIds4]]
  479: #    puts "3:[time {set ids [subjFindIds3]} 2]\t:[llength $ids]"
  480: #    puts "2:[time {set ids [subjFindIds2]} 2]\t:[llength $ids]"
  481: #    puts "1:[time {set ids [subjFindIds1]} 2]\t:[llength $ids]"
  482: 
  483: }
  484: 
  485: proc subjFindName {} {
  486:     global gSubj
  487:     
  488:     if {[catch {set text [string toupper [$gSubj(response) get sel.first sel.last]]}]} {
  489: 	set text [string toupper [$gSubj(response) get 0.0 end]]
  490:     }
  491:     set text [split $text "{}!@\#\$%^&*()_-+=|\\,.<>/?'\";:`~ \n\t"]
  492:     set result ""
  493:     set length [llength $gSubj(allname)]
  494:     foreach word $text {
  495: 	if { [string length $word] == 0 } { continue }
  496: 	for { set i 0 } { $i < $length } { incr i } {
  497: 	    set name [string toupper [lindex $gSubj(allname) $i]]
  498: 	    if { [set find [lsearch -glob $name *$word*]] != -1 } {
  499: 		lappend result $i
  500: 	    }
  501: 	}
  502:     }
  503:     set result [lunique $result]
  504:     foreach index $result {
  505: 	lappend temp [list [lindex $gSubj(allstunum) $index] \
  506: 			  [lindex $gSubj(allname) $index]]
  507:     }
  508:     if {[catch {set temp [lsort $temp]}]} {
  509: 	displayMessage "No Student found."
  510: 	return
  511:     }
  512:     set selected [multipleChoice {} "Select which student you want." $temp 1]
  513:     if {$selected == ""} { return }
  514:     set done 0
  515:     if { [llength $selected] == 2 } { 
  516: 	if { [lindex [lindex $selected 0] 0] == "" } { 
  517: 	    set selected [lindex $selected 0]
  518: 	    set done 1
  519: 	}
  520:     }
  521:     if { !$done } { foreach person $selected { lappend idlist [lindex $selected 0] } }
  522:     subjInsertIds $idlist
  523:     subjPicts
  524: }
  525: 
  526: proc subjGetNameFromId { id } {
  527:     global gSubj
  528:     return [lindex $gSubj(allname) [lsearch $gSubj(allstunum) $id]]
  529: }
  530: 
  531: proc subjGetIdList {} {
  532:     global gSubj
  533:     set list [$gSubj(idlist) get 0 end]
  534:     set id ""
  535:     foreach element $list {
  536: 	append id "[lindex $element 0] "
  537:     }
  538:     return $id
  539: }
  540: 
  541: proc subjInsertIds { selected } {
  542:     global gSubj
  543:     set current [subjGetIdList]
  544:     foreach person $selected {lappend current [lindex $person 0]}
  545:     set current [lsort [lunique $current]]
  546:     $gSubj(idlist) delete 0 end
  547:     foreach id $current {
  548: 	$gSubj(idlist) insert end "$id [subjGetNameFromId $id]"
  549:     }
  550: }
  551: 
  552: proc subjDeleteId {} {
  553:     global gSubj
  554:     $gSubj(idlist) delete [$gSubj(idlist) curselection]
  555:     subjPicts
  556: }
  557: 
  558: proc subjAddId {} {
  559:     global gSubj
  560:     getOneStudent {} $gSubj(dir) id name
  561:     if { $id == "" } { return }
  562:     subjInsertIds $id
  563: }
  564: 
  565: proc subjPrev {} {
  566:     global gSubj
  567:     if  { $gSubj(current) > 0 } {
  568: 	incr gSubj(current) -2
  569: 	subjNext
  570:     }
  571: }
  572: 
  573: proc subjMessage { mesg {tag normal} } {
  574:     global gSubj
  575:     displayMessage $mesg
  576: #    $gSubj(msg) insert end "[clock format [clock seconds] -format {%I:%M:%S}] - $mesg\n" $tag
  577: #    $gSubj(msg) see end
  578: }
  579: 
  580: proc subjAddPict { id } {
  581:     global gSubj
  582:     set gif [file join $gSubj(dir) photo gif $id.gif]
  583:     if { ![file exists $gif] } { return }
  584:     lappend gSubj(imagelist) [set image [image create photo]]
  585:     $image read $gif
  586:     set a [llength $gSubj(imagelist)]
  587:     $gSubj(canvas) create image [expr ($a-1)*200] 20 -image $image -anchor nw
  588:     $gSubj(canvas) create text [expr ($a-1)*200] 10 -text $id -anchor nw
  589:     $gSubj(canvas) create text [expr ($a-1)*200] 0 -text [subjGetNameFromId $id] \
  590: 	-anchor nw
  591:     $gSubj(canvas) configure -scrollregion "1 1 [expr ($a)*200] 200"
  592:     update idletasks
  593:     return $a
  594: }
  595: 
  596: proc subjConvertPict { id } {
  597:     global gSubj
  598:     set gif [file join $gSubj(dir) photo gif $id.gif]
  599:     set jpg [file join $gSubj(dir) photo jpg $id.jpg]
  600:     if { ![file exists $gif] } {
  601: 	if { [file exists $jpg] } {
  602: 	    exec djpeg -outfile $gif $jpg
  603: 	}
  604:     }
  605: }
  606: 
  607: proc subjPicts {} {
  608:     global gSubj 
  609: 
  610:     $gSubj(canvas) delete all
  611:     catch { foreach image $gSubj(imagelist) { catch {image delete $image} } }
  612:     set gSubj(imagelist) ""
  613:     set idlist [subjGetIdList]
  614:     foreach id $idlist {
  615: 	subjConvertPict $id
  616: 	set num [subjAddPict $id]
  617:     } 
  618: }
  619: 
  620: proc subjPict {} {
  621:     global gSubj
  622:     if { $gSubj(pict) } {
  623: 	pack $gSubj(pictFrame)
  624: 	pack configure $gSubj(pictFrame) -fill x
  625:     } else {
  626: 	pack forget $gSubj(pictFrame)
  627:     }
  628: }
  629: 
  630: proc subjPrint {} {
  631:     global gSubj
  632:     set lprCommand [getLprCommand quiztemp.txt]
  633:     if {$lprCommand == "Cancel"} { return }
  634:   
  635:     set fileId [open "quiztemp.txt" w] 
  636:     set subid [lindex $gSubj(stunums) $gSubj(current)]
  637:     if { $subid != "" } {
  638: 	set file [file join $gSubj(dir) records set$gSubj(set) \
  639: 		      problem$gSubj(quest) $subid]
  640: 	puts $fileId "Submitted at [clock format [file mtime $file ]]"
  641: 	puts $fileId "By Student:\n [string trimright [subjGetNameFromId $subid]] ($subid)"
  642:     }
  643:     if { [llength [subjGetIdList]] > 1 } {
  644: 	puts $fileId "Additional Authors:"
  645: 	foreach id [subjGetIdList] {
  646: 	    if { $id == $subid } { continue }
  647: 	    puts $fileId " [string trimright [subjGetNameFromId $id]] ($id)"
  648: 	}
  649:     }
  650:     puts $fileId ""
  651:     puts -nonewline $fileId "[ $gSubj(response) get 0.0 end-1c ]"
  652:     close $fileId
  653: 
  654:     set errorMsg ""
  655:     set error [catch {set output [ eval "exec $lprCommand" ] } errorMsg ]
  656:     
  657:     if { $error == 1 } {
  658:         displayError "An error occurred while printing: $errorMsg"
  659:     } else {
  660: 	displayMessage "Print job sent to the printer.\n $output"
  661:     }
  662:     exec rm -f quiztemp.txt
  663: }
  664: 
  665: proc subjGoto {} {
  666:     global gSubj
  667:     subjGetOneStudent {} $gSubj(dir) id name
  668:     if { $id == "" } { return }
  669:     if { [file exists [file join $gSubj(dir) records set$gSubj(set) problem$gSubj(quest) $id] ] } {
  670: 	set gSubj(current) [expr [lsearch $gSubj(stunums) $id] - 1]
  671: 	subjNext
  672:     } else {
  673: 	displayMessage "Student $id did not submit an answer."
  674:     }
  675: }
  676: 
  677: proc subjGetUngraded {} {
  678:     global gSubj
  679: 
  680:     set idlist ""
  681:     foreach stunum $gSubj(stunums) {
  682: 	if {[catch {set gSubj(done.$stunum.score)}]} {
  683: 	    lappend idlist $stunum
  684: 	}
  685:     }
  686:     return [multipleChoice {} "Select which student you want to grade." $idlist 1]
  687: }
  688: 
  689: proc subjGetOneStudent { window path idVar nameVar {message "" } } {
  690:     upvar $idVar id
  691:     upvar $nameVar name
  692:     
  693:     set select [tk_dialog $window.dialog "$message Student select method" \
  694: 		    "Select student by:" "" "" "Student Number" \
  695: 		    "Student Name" "Not Yet Graded" "Cancel"]
  696:     if { $select == 3 } { 
  697: 	set id ""
  698: 	set name ""
  699: 	return 
  700:     }
  701:     if { $select == 2 } {
  702: 	set id [subjGetUngraded]
  703: 	set name [subjGetNameFromId $id]
  704: 	return
  705:     }
  706:     set done 0
  707:     while { ! $done } {
  708: 	if { $select } { set search "name" } { set search "number" }
  709: 	set pattern [ getString $window "$message Please enter a student $search." ]
  710: 	if {$pattern == "" } {
  711: 	    set done 1
  712: 	    set id ""
  713: 	    set name ""
  714: 	    continue
  715: 	}
  716: 	if { $select } {
  717: 	    set matched_entries [findByStudentName $pattern $path]
  718: 	} else {
  719: 	    set matched_entries [findByStudentNumber $pattern $path]
  720: 	}
  721: 	if { [llength $matched_entries] == 0 } {
  722: 	    displayMessage "No student found. Please re-enter student $search."
  723: 	} elseif { [llength $matched_entries] == 1 } {
  724: 	    set id [lindex [lindex $matched_entries 0] 0]
  725: 	    set name [lindex [lindex $matched_entries 0] 1]
  726: 	    set done 1
  727: 	} elseif { [llength $matched_entries] < 30 } {
  728: 	    set select [ multipleChoice $window \
  729: 			     "Matched Student Records, Select one" \
  730: 			     $matched_entries ]
  731: 	    if { $select == "" } { 
  732: 		set id ""; set name ""
  733: 		return 
  734: 	    }
  735: 	    set id [lindex $select 0]
  736: 	    set name [lindex $select 1]
  737: 	    set done 1
  738: 	} else {
  739: 	    displayMessage "There were [llength $matched_entries], please enter more data to narrow the search."
  740: 	}
  741:     }
  742: }
  743: 
  744: ###########################################################
  745: # subjSendResponse
  746: ###########################################################
  747: ###########################################################
  748: ###########################################################
  749: proc subjSendResponse {} {
  750:     global gSubj gCapaConfig
  751: 
  752:     if { "" == [set which [$gSubj(responseList) curselection]]} {
  753: 	displayMessage "Please select a message to send."
  754: 	return
  755:     }
  756:     incr which
  757: 
  758:     set message ""
  759: 
  760:     set stuList [$gSubj(idlist) get 0 end]
  761:     foreach stu $stuList {
  762: 	set stu [lindex $stu 0]
  763: 	set index [lsearch $gSubj(allstunum) $stu]
  764: 	set name [lindex $gSubj(allname) $index]
  765: 	set email [lindex $gSubj(allemail) $index]
  766: 	#puts "$name:[split $name ,]:[lindex [split $name ,] 1]:[lindex [lindex [split $name ,] 1] 0]:$index:$stu"
  767: 	#puts [lsearch $gSubj(allemail) albertel@pilot.msu.edu]
  768: 	set first_name [lindex [lindex [split $name ,] 1] 0]
  769: 	set last_name [lindex [split $name , ] 0]
  770: 	set score $gSubj(score)
  771: 	regsub -all -- \\\$last_name $gSubj(response.$which) $last_name message
  772: 	regsub -all -- \\\$first_name $message $first_name message
  773: 	regsub -all -- \\\$score $message $score message
  774: #	set message [subst -nobackslashes -nocommands $gSubj(response.$which)]
  775: 	if { [regexp -- (^Subject:\[^\n\]*)(\n)(.*) $message matchvar subjline newline messagebody] } {
  776: 	    set subject "$subjline Class [file tail $gSubj(dir)], Set $gSubj(set), Question $gSubj(quest)"
  777: 	    set message $messagebody
  778: 	} else {
  779: 	    set subject "Subject: Class [file tail $gSubj(dir)], Set $gSubj(set), Question $gSubj(quest)"
  780: 	}
  781: 	displayMessage "$message sent to $email"
  782: 	exec echo $message | $gCapaConfig(mail_command) -s $subject $email
  783:     }
  784: }
  785: 
  786: ###########################################################
  787: # subjIndexResponse
  788: ###########################################################
  789: ###########################################################
  790: ###########################################################
  791: proc subjIndexResponse {} {
  792:     global gSubj
  793:     
  794:     $gSubj(responseList) delete 0 end
  795: 
  796:     set i 0
  797:     foreach element [lsort -dictionary [array names gSubj "response.*"]] {
  798: 	regsub -all -- "\[\n\r\t\]+" [string range $gSubj($element) 0 37] " " head
  799: 	$gSubj(responseList) insert end "[incr i].$head"
  800:     }
  801: }
  802: 
  803: ###########################################################
  804: # subjSaveResponse
  805: ###########################################################
  806: ###########################################################
  807: ###########################################################
  808: proc subjSaveResponse {} {
  809:     global gSubj
  810:     
  811:     set num [incr gSubj(numresponse)]
  812:     set gSubj(response.$num) [$gSubj(responseNew) get 0.0 end-1c]
  813:     destroy [winfo toplevel $gSubj(responseNew)]
  814:     subjIndexResponse
  815:     $gSubj(responseList) selection set end
  816:     $gSubj(responseList) see end
  817: }
  818: 
  819: ###########################################################
  820: # subjNewResponse
  821: ###########################################################
  822: ###########################################################
  823: ###########################################################
  824: proc subjNewResponse {} {
  825:     global gSubj gWindowMenu
  826:    
  827:     if { [winfo exists .addresponse] } { 
  828: 	capaRaise .addresponse
  829: 	return 
  830:     }
  831:     set response [toplevel .addresponse]
  832:     $gWindowMenu add command -label "AddingResponse" -command "capaRaise $response"
  833:     wm title $response "Adding a New Response"  
  834: 
  835:     set textFrame [frame $response.text]
  836:     set buttonFrame [frame $response.button]
  837:     pack $textFrame $buttonFrame
  838: 
  839:     set gSubj(responseNew) [text $textFrame.text -yscrollcommand \
  840: 	    "$textFrame.scroll set" -wrap char -height 15]
  841:     scrollbar $textFrame.scroll -command "$textFrame.text yview"
  842:     pack $textFrame.text $textFrame.scroll -side left -expand 1
  843:     pack configure $textFrame.scroll -fill y
  844: 
  845:     button $buttonFrame.save -text Save -command "subjSaveResponse"
  846:     button $buttonFrame.forget -text Cancel -command "destroy $response"
  847:     pack $buttonFrame.save $buttonFrame.forget -side left
  848: }
  849: 
  850: ###########################################################
  851: # subjDeleteResponse
  852: ###########################################################
  853: ###########################################################
  854: ###########################################################
  855: proc subjDeleteResponse {} {
  856:     global gSubj
  857:     if { [winfo exists .editresponse] } { 
  858: 	displayMessage "Please finish with editing the response, before deleting responses."
  859: 	return
  860:     }
  861:     if { "" == [set which [$gSubj(responseList) curselection]]} { return }
  862:     incr which
  863:     if { [catch {unset gSubj(response.$which)}] } {
  864: 	#puts [array names gSubj response.*]
  865: 	return
  866:     }
  867:     for {set i [expr $which + 1]} { [info exists gSubj(response.$i)] } {incr i} {
  868: 	set j [expr $i - 1]
  869: 	set gSubj(response.$j) $gSubj(response.$i)
  870: 	unset gSubj(response.$i)
  871:     }
  872:     set gSubj(numresponse) [expr $i - 2]
  873:     subjIndexResponse
  874:     $gSubj(responseList) see [incr which -2]
  875: }
  876: 
  877: ###########################################################
  878: # subjEditResponse
  879: ###########################################################
  880: ###########################################################
  881: ###########################################################
  882: proc subjEditResponse {} {
  883:     global gSubj gWindowMenu
  884: 
  885:     if { [winfo exists .editresponse] } { capaRaise .editresponse ; return }
  886:     if { "" == [set which [$gSubj(responseList) curselection]]} { return }
  887:     incr which
  888: 
  889:     set response [toplevel .editresponse ]
  890:     $gWindowMenu add command -label "EditingResponse" -command "capaRaise $response"
  891:     wm title $response "Editing a Response"  
  892: 
  893:     set textFrame [frame $response.text]
  894:     set buttonFrame [frame $response.button]
  895:     pack $textFrame $buttonFrame
  896: 
  897:     set gSubj(responseEdit) [text $textFrame.text -yscrollcommand \
  898: 	    "$textFrame.scroll set" -wrap char -height 15]
  899:     scrollbar $textFrame.scroll -command "$textFrame.text yview"
  900:     pack $textFrame.text $textFrame.scroll -side left -expand 1
  901:     pack configure $textFrame.scroll -fill y
  902:     $gSubj(responseEdit) insert 0.0 $gSubj(response.$which)
  903: 
  904:     set gSubj(editresponsedone) 0
  905:     button $buttonFrame.save -text Save -command "set gSubj(editresponsedone) 1"
  906:     button $buttonFrame.forget -text Cancel -command "set gSubj(editresponsedone) 0"
  907:     pack $buttonFrame.save $buttonFrame.forget -side left
  908:     vwait gSubj(editresponsedone)
  909:     if { $gSubj(editresponsedone) } {
  910: 	set gSubj(response.$which) [$gSubj(responseEdit) get 0.0 end-1c]	
  911: 	subjIndexResponse
  912: 	$gSubj(responseList) selection set $which
  913: 	$gSubj(responseList) see $which
  914:     } 
  915:     destroy $response
  916: }
  917: 
  918: ###########################################################
  919: # subjViewResponse
  920: ###########################################################
  921: ###########################################################
  922: ###########################################################
  923: proc subjViewResponse {} {
  924:     global gSubj gUniqueNumber gWindowMenu
  925: 
  926:     if { "" == [set which [$gSubj(responseList) curselection]]} { return }
  927:     incr which
  928:     set num [incr gUniqueNumber]
  929: 
  930:     set response [toplevel .viewresponse$num ]
  931:     $gWindowMenu add command -label "ViewingResponse $which" \
  932: 	-command "capaRaise $response"
  933:     wm title $response "Viewing Response $which"  
  934: 
  935:     set textFrame [frame $response.text]
  936:     set buttonFrame [frame $response.button]
  937:     pack $textFrame $buttonFrame
  938: 
  939:     text $textFrame.text -yscrollcommand "$textFrame.scroll set" -wrap char -height 15
  940:     scrollbar $textFrame.scroll -command "$textFrame.text yview"
  941:     pack $textFrame.text $textFrame.scroll -side left -expand 1
  942:     pack configure $textFrame.scroll -fill y
  943:     $textFrame.text insert 0.0 $gSubj(response.$which)
  944:     $textFrame.text configure -state disabled
  945: 
  946:     button $buttonFrame.forget -text Dismiss -command "destroy $response"
  947:     pack $buttonFrame.forget -side left
  948: }
  949: 
  950: ###########################################################
  951: # subjUpdateResponse
  952: ###########################################################
  953: ###########################################################
  954: ###########################################################
  955: proc subjUpdateResponse {} {
  956:     global gSubj
  957: 
  958:     $gSubj(response) tag delete keyword
  959:     $gSubj(response) tag configure keyword -background green
  960:     set startindex 0.0
  961:     set lastindex [$gSubj(response) index end]
  962:     while { 1 } {
  963: 	set endindex [$gSubj(response) index "$startindex wordend"]
  964: #	puts "$startindex -> $endindex"
  965: 	set word [string trim [string toupper [$gSubj(response) get $startindex $endindex]]]
  966: 	if { $word != "" } {
  967: 	    #	puts "Word :$word:"
  968: 	    foreach keyword $gSubj(keywords) {
  969: 		set keyword [string toupper [lindex $keyword 1]]
  970: 		if { [lsearch -exact $keyword $word] != -1 } {
  971: 		    $gSubj(response) tag add keyword $startindex $endindex
  972: 		}
  973: 	    }
  974: 	    #	puts [$gSubj(response) index "$endindex+1c"]
  975: 	    #	puts [$gSubj(response) index "$endindex wordstart"]
  976: 	    #	puts [$gSubj(response) index "$endindex+1c wordstart"]
  977: 	    
  978: 	    #	set startindex [$gSubj(response) index "$endindex + 1c"]
  979: 	}
  980: 	set startindex $endindex
  981: 	if { $startindex == $lastindex } { break }
  982:     }
  983: }
  984: 
  985: ###########################################################
  986: # subjUpdateKeywords
  987: ###########################################################
  988: ###########################################################
  989: ###########################################################
  990: proc subjUpdateKeywords {} {
  991:     global gSubj
  992:     $gSubj(keyword) delete 0.0 end
  993:     set lokeyword ""
  994: #    puts $gSubj(keywords)
  995:     foreach keyword $gSubj(keywords) { lappend lokeyword [lindex $keyword 0] }
  996:     if { $lokeyword == "" } { return }
  997:     set lokeyword [lsort $lokeyword]
  998:     set max 0
  999:     foreach key $lokeyword {
 1000: 	if { [string length $key] > $max } { set max [string length $key] }
 1001:     }
 1002:     incr max
 1003:     set numcol [expr 60/$max]
 1004:     set end [llength $lokeyword]
 1005:     set lastline 0
 1006:     for { set i 0 } { $i < $end } { incr i } {
 1007: 	set line [expr $i/$numcol]
 1008: 	set col [expr $i%$numcol*$max]
 1009: #	puts $line.$col
 1010: 	$gSubj(keyword) insert end [format "%-[set max]s" [lindex $lokeyword $i]]
 1011: 	if {($col + (2*$max)) > 60} {
 1012: #	    puts "Putting in newlne"
 1013: 	    $gSubj(keyword) insert end "\n"
 1014: 	    set lastline $line
 1015: 	}
 1016:     }
 1017:     subjUpdateResponse
 1018: }
 1019: 
 1020: ###########################################################
 1021: # subjAddKeyword
 1022: ###########################################################
 1023: ###########################################################
 1024: ###########################################################
 1025: proc subjAddKeyword {} {
 1026:     global gSubj 
 1027: 
 1028:     if { "" == [set newword [getString [winfo toplevel $gSubj(keyword)] "Enter a new keyword" nospace ]]} {
 1029: 	return
 1030:     }
 1031:     set i 0
 1032:     foreach keyword $gSubj(keywords) {
 1033: 	if {-1 != [lsearch $keyword $newword]} { break }
 1034: 	incr i
 1035:     }
 1036:     if { $i >= [llength $gSubj(keywords)] } {
 1037:         lappend gSubj(keywords) [list $newword [list $newword]]
 1038: 	subjUpdateKeywords
 1039:     }
 1040: }
 1041: 
 1042: ###########################################################
 1043: # subjAddKeywordSpelling
 1044: ###########################################################
 1045: ###########################################################
 1046: ###########################################################
 1047: proc subjAddKeywordSpelling {} {
 1048:     global gSubj
 1049: 
 1050:     if { [catch {set word [$gSubj(keyword) get sel.first sel.last]}]} { return }
 1051:     if { "" == [set newspell [getString [winfo toplevel $gSubj(keyword)] "Enter a new spelling for $word" nospace ]]} {
 1052: 	return
 1053:     }
 1054:     set i 0
 1055:     foreach keyword $gSubj(keywords) {
 1056: 	if {-1 != [lsearch $keyword $word]} { break }
 1057: 	incr i
 1058:     }
 1059: 
 1060:     set gSubj(keywords) [lreplace $gSubj(keywords) $i $i \
 1061: 			     [list $word [concat [lindex $keyword 1] $newspell]]]
 1062:     subjUpdateKeywords
 1063: }
 1064: 
 1065: ###########################################################
 1066: # subjSeeKeyword
 1067: ###########################################################
 1068: ###########################################################
 1069: ###########################################################
 1070: proc subjSeeKeyword {} {
 1071:     global gSubj gPromptMC
 1072:     
 1073:     if { [catch {set word [$gSubj(keyword) get sel.first sel.last]}]} { return }
 1074:     set i 0
 1075:     foreach keyword $gSubj(keywords) {
 1076: 	if {-1 != [lsearch $keyword $word]} { break }
 1077: 	incr i
 1078:     }
 1079: 
 1080:     set which $i
 1081:     set setWin [toplevel $gSubj(keyword).keyword]
 1082:     
 1083:     set msgFrame [frame $setWin.msgFrame]
 1084:     set valFrame [frame $setWin.valFrame]
 1085:     set buttonFrame [frame $setWin.buttonFrame]
 1086:     pack $msgFrame $valFrame $buttonFrame
 1087:     pack configure $valFrame -expand 1 -fill both
 1088: 
 1089:     message $msgFrame.msg -text "Alternate spellings for [lindex $keyword 0]" \
 1090: 	-aspect 3000
 1091:     pack $msgFrame.msg
 1092:     
 1093:     set maxWidth 1
 1094:     foreach choice [lindex $keyword 1] {
 1095: 	if {[string length $choice] > $maxWidth} {set maxWidth [string length $choice]}
 1096:     }
 1097:     listbox $valFrame.val -width [expr $maxWidth + 2] \
 1098: 	-yscrollcommand "$valFrame.scroll set" -selectmode single
 1099:     scrollbar $valFrame.scroll -command "$valFrame.val yview"
 1100:     pack $valFrame.val $valFrame.scroll -side left
 1101:     pack configure $valFrame.val -expand 1 -fill both 
 1102:     pack configure $valFrame.scroll -expand 0 -fill y
 1103:     foreach choice [lsort [lrange [lindex $keyword 1] 1 end]] { 
 1104: 	$valFrame.val insert end $choice 
 1105:     }
 1106: 
 1107:     button $buttonFrame.select -text "Delete" -command { set gPromptMC(ok) 1 }
 1108:     frame $buttonFrame.spacer -width 10
 1109:     button $buttonFrame.cancel -text "Dismiss" -command { set gPromptMC(ok) 0 }
 1110:     pack $buttonFrame.select $buttonFrame.cancel -side left
 1111: 
 1112:     bind $setWin <Return> "set gPromptMC(ok) 0"
 1113:     Centre_Dialog $setWin default
 1114:     update idletasks
 1115:     focus $setWin
 1116:     capaRaise $setWin
 1117:     capaGrab $setWin
 1118:     while { 1 } {
 1119: 	update idletasks
 1120: 	vwait gPromptMC(ok)
 1121: 	if { $gPromptMC(ok) == 0 } { break }
 1122: 	set select [$valFrame.val curselection]
 1123: 	if { $select != "" } { 
 1124: 	    $valFrame.val delete $select
 1125: 	} 
 1126:     }
 1127:     set spellings [lindex $keyword 0]
 1128:     for {set i 0} {$i < [$valFrame.val index end]} { incr i } { 
 1129: 	lappend spellings [$valFrame.val get $i]
 1130:     }
 1131:     capaGrab release $setWin
 1132:     destroy $setWin
 1133: 
 1134:     set gSubj(keywords) [lreplace $gSubj(keywords) $which $which \
 1135: 			     [list [lindex $keyword 0] $spellings ]]
 1136: 
 1137:     subjUpdateKeywords
 1138: }
 1139: 
 1140: ###########################################################
 1141: # subjDeleteKeyword
 1142: ###########################################################
 1143: ###########################################################
 1144: ###########################################################
 1145: proc subjDeleteKeyword {} {
 1146:     global gSubj
 1147:     
 1148:     if { [catch {set word [$gSubj(keyword) get sel.first sel.last]}]} { return }
 1149:     set newkeyword ""
 1150:     foreach keyword $gSubj(keywords) {
 1151: 	if {-1 == [lsearch $keyword $word]} { lappend newkeyword $keyword }
 1152:     }
 1153:     set gSubj(keywords) $newkeyword
 1154:     subjUpdateKeywords
 1155: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>