# classl editor # Copyright (C) 1992-2000 Michigan State University # # The CAPA system is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # The CAPA system is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public # License along with the CAPA system; see the file COPYING. If not, # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # As a special exception, you have permission to link this program # with the TtH/TtM library and distribute executables, as long as you # follow the requirements of the GNU GPL in regard to all of the # software in the executable aside from TtH/TtM. ########################################################### # createClasslEditor ########################################################### ########################################################### ########################################################### proc createClasslEditor { classlFile } { global gUniqueNumber gWindowMenu gWindow gTitle gClassl gFile \ gClosed set error [ catch {set fileId [open $classlFile "r"]}] if { $error } { displayError "Unable to open a $classlFile." return } close $fileId set num [incr gUniqueNumber] set gFile($num) $classlFile set classlWin [toplevel .classlwindow$num] $gWindowMenu add command -label "Classl $classlFile" \ -command "capaRaise $classlWin" wm title $classlWin "Classl $classlFile" set menuFrame [frame $classlWin.menu -borderwidth 3 -relief raised] set infoFrame [frame $classlWin.infoFrame] set actionFrame [frame $classlWin.actionFrame] set windowFrame [frame $classlWin.windowFrame] pack $menuFrame $infoFrame $actionFrame $windowFrame pack configure $windowFrame -expand 1 -fill both pack configure $menuFrame -fill x -anchor w #menu menubutton $menuFrame.file -text File -menu $menuFrame.file.m menubutton $menuFrame.edit -text Copy -menu $menuFrame.edit.m pack $menuFrame.file $menuFrame.edit -side left set fileMenu [ menu $menuFrame.file.m ] set editMenu [ menu $menuFrame.edit.m ] $fileMenu add command -label Open -accelerator "Alt+o" \ -command "specifyClass createClasslEditor" bind $classlWin "specifyClass createClasslEditor" $fileMenu add command -label Save -command "saveClassl $num 0" \ -accelerator "Alt+s" bind $classlWin "saveClassl $num 0" $fileMenu add command -label "Save As" -command "saveClassl $num 1" \ -accelerator "Alt+S" bind $classlWin "saveClassl $num 1" $fileMenu add command -label Print -command "printClassl $num" $fileMenu add command -label Close -command "closeClassl $num" \ -accelerator "Alt+w" bind $classlWin "closeClassl $num" $editMenu add command -label "Copy StudentNum" -command "classlCopy $num stunum" \ -accelerator "Alt+c" bind $classlWin "classlCopy $num stunum" $editMenu add command -label "Copy Name" -command "classlCopy $num name" \ -accelerator "Alt+n" bind $classlWin "classlCopy $num name" $editMenu add command -label "Copy Email" -command "classlCopy $num email" \ -accelerator "Alt+e" bind $classlWin "classlCopy $num email" #info #action button $actionFrame.add -text "Add" -command "classlAdd $num" button $actionFrame.edit -text "Edit" -command "classlEdit $num" button $actionFrame.save -text "Save" -command "saveClassl $num 1" button $actionFrame.delete -text "Delete" -command "classlDelete $num" button $actionFrame.section -text "Change Section" -command "classlSectionChange $num" button $actionFrame.sort -text "Sort" -command "classlSort $num" button $actionFrame.print -text "Print" -command "classlPrint $num" button $actionFrame.find -text "Find" -command "classlFind $num" button $actionFrame.merge -text "Merge" -command "classlMerge $num" pack $actionFrame.add $actionFrame.edit $actionFrame.save $actionFrame.delete \ $actionFrame.section $actionFrame.sort $actionFrame.print $actionFrame.find \ $actionFrame.merge -side left #window set leftFrame [frame $windowFrame.left] set rightFrame [frame $windowFrame.right] pack $leftFrame $rightFrame -side left pack configure $leftFrame -expand 1 -fill both pack configure $rightFrame -fill y #FIXME need to set the title width based on the widest occuring element in #the listbox scrollbar $rightFrame.scroll -orient v -command "$leftFrame.classl yview" pack $rightFrame.scroll -fill y -expand 1 -pady 20 set gTitle($num) [format "%-100s" "Class Section StuNum Name E-mail"] entry $leftFrame.title -textvariable gTitle($num) -width 80 \ -state disabled -xscrollcommand "$leftFrame.scroll set" set gClassl($num) [ listbox $leftFrame.classl -width 80 -height 30 \ -xscrollcommand "$leftFrame.scroll set" \ -yscrollcommand "$rightFrame.scroll set" \ -exportselection 0] scrollbar $leftFrame.scroll -orient h -command \ "scrolltwo {$leftFrame.classl xview} {$leftFrame.title xview}" pack $leftFrame.title $leftFrame.classl $leftFrame.scroll -side top pack configure $leftFrame.title $leftFrame.scroll -fill x pack configure $leftFrame.classl -fill both -expand 1 set fileId [open $classlFile "r"] while { 1 } { set aline [gets $fileId] if { [eof $fileId ] } { break } $gClassl($num) insert end [format "%-100s" $aline] } set gClassl($num.changed) 0 set gClassl($num.changedlast) 0 set gClosed($num) 0 Centre_Dialog $classlWin default trace variable gClassl($num.changed) w updateClasslStatus } ########################################################### # closeClassl ########################################################### ########################################################### ########################################################### proc closeClassl { num { mustClose 0 } } { global gWindowMenu gWindow gTitle gClassl gFile gClosed if { ![winfo exists $gClassl($num)] } { return } if { $gClosed($num) } { return } if { $gClassl($num.changed) == 1 } { if { [askToSave "Do you wish to save $gFile($num)?" "saveClassl $num" ] == "Cancel" && ( ! $mustClose ) } { return } } if { ( ! $mustClose ) && ( [makeSure "Are you sure you wish to stop editing $gFile($num)?"] == "Cancel" ) } { return } set gClosed($num) 1 destroy [winfo toplevel $gClassl($num)] removeWindowEntry "Classl $gFile($num)" } ########################################################### # saveClassl ########################################################### ########################################################### ########################################################### proc saveClassl { num {saveAs 0}} { global gFile gClassl if { ![winfo exists $gClassl($num)] } { return } if { $saveAs } { set file [tk_getSaveFile -title "Enter name to Save As" \ -initialdir [file dirname "$gFile($num)"]] if {$file == "" } { return } set gFile($num) $file } set fileId [open "$gFile($num)" "w"] foreach line [$gClassl($num) get 0 end] { puts $fileId $line } close $fileId set gClassl($num.changed) 0 } ########################################################### # classlSectionChange ########################################################### ########################################################### ########################################################### proc classlSectionChange { num } { global gFile gClassl gWindowMenu if { [set which [$gClassl($num) curselection]] == "" } { displayMessage "Select a student first" return } if { [winfo exists .classlsection$num] } { capaRaise .classlsection$num return } set sectionChange [toplevel .classlsection$num] $gWindowMenu add command -label "Section Change" \ -command "capaRaise $sectionChange" wm title $sectionChange [file dirname $sectionChange] set infoFrame [frame $sectionChange.info] set entryFrame [frame $sectionChange.entry] set buttonFrame [frame $sectionChange.button] pack $infoFrame $entryFrame $buttonFrame -side top label $infoFrame.label -text "Enter New Section Number" pack $infoFrame.label label $entryFrame.label -text "Section:" entry $entryFrame.section -textvariable gClassl($num.section) -width 3 \ -validate key -validatecommand "limitEntry %W 3 number %P" pack $entryFrame.label $entryFrame.section -side left set gClassl($num.done) 0 button $buttonFrame.change -text "Change" -command "set gClassl($num.done) 1" button $buttonFrame.cancel -text "Cancel" -command "set gClassl($num.done) 0" pack $buttonFrame.change $buttonFrame.cancel -side left Centre_Dialog $sectionChange default update focus $sectionChange capaGrab $sectionChange vwait gClassl($num.done) capaGrab release $sectionChange if { $gClassl($num.done) } { set record [$gClassl($num) get $which] set record "[string range $record 0 9][format %03d $gClassl($num.section)][string range $record 13 end]" $gClassl($num) delete $which $gClassl($num) insert $which $record set gClassl($num.changed) 1 } destroy $sectionChange } ########################################################### # classlSort ########################################################### ########################################################### ########################################################### proc classlSort { num } { global gFile gClassl gWindowMenu if { [winfo exists .classlsort$num] } { capaRaise .classlsort$num return } set sortClassl [toplevel .classlsort$num] $gWindowMenu add command -label "Sort Classl" \ -command "capaRaise $sortClassl" wm title $sortClassl [file dirname $sortClassl] set infoFrame [frame $sortClassl.info] set buttonFrame [frame $sortClassl.button] pack $infoFrame $buttonFrame -side top label $infoFrame.label -text "How would you like the classl sorted?" pack $infoFrame.label set gClassl($num.done) 0 button $buttonFrame.section -text "Sort By Section" \ -command "set gClassl($num.done) Section" button $buttonFrame.name -text "Sort By Name" \ -command "set gClassl($num.done) Name" button $buttonFrame.cancel -text "Cancel" -command "set gClassl($num.done) 0" pack $buttonFrame.section $buttonFrame.name $buttonFrame.cancel -side left Centre_Dialog $sortClassl default update focus $sortClassl capaGrab $sortClassl vwait gClassl($num.done) capaGrab release $sortClassl if { $gClassl($num.done) != 0 } { sortClassl$gClassl($num.done) $num set gClassl($num.changed) 1 } destroy $sortClassl } ########################################################### # classlCompare ########################################################### ########################################################### ########################################################### proc classlCompare { field1 field2 val1 val2 } { switch $field1 { section { set a [string range $val1 10 12] set b [string range $val2 10 12] } name { set a " [string range $val1 24 55]" set b " [string range $val2 24 55]" } } switch $field2 { name { append a " [string range $val1 24 55]" append b " [string range $val2 24 55]" } default {} } return [string compare $a $b] } ########################################################### # sortClasslSection ########################################################### ########################################################### ########################################################### proc sortClasslSection { num } { global gClassl set allitems [$gClassl($num) get 0 end] set newitems [lsort -command "classlCompare section name" $allitems] $gClassl($num) delete 0 end eval "$gClassl($num) insert end $newitems" } ########################################################### # sortClasslName ########################################################### ########################################################### ########################################################### proc sortClasslName { num } { global gClassl set allitems [$gClassl($num) get 0 end] set newitems [lsort -command "classlCompare name {}" $allitems] $gClassl($num) delete 0 end eval "$gClassl($num) insert end $newitems" } ########################################################### # makeClasslEntryEditor ########################################################### ########################################################### ########################################################### proc makeClasslEntryEditor { num window title buttonname } { global gClassl gWindowMenu if { [winfo exists $window] } { capaRaise $window return 1 } set add [toplevel $window] $gWindowMenu add command -label "$title" -command "capaRaise $add" wm title $add "$title" set infoFrame [frame $add.info] set buttonFrame [frame $add.button] pack $infoFrame $buttonFrame -side top -anchor w set classFrame [frame $infoFrame.class] set sectionFrame [frame $infoFrame.section] set stuFrame [frame $infoFrame.stu] set nameFrame [frame $infoFrame.name] set emailFrame [frame $infoFrame.email] pack $classFrame $sectionFrame $stuFrame $nameFrame $emailFrame -side top -anchor w label $classFrame.label -text "Class Name" -width 20 entry $classFrame.entry -textvariable gClassl($num.editclass) -width 9 \ -validate key -validatecommand "limitEntry %W 9 any %P" pack $classFrame.label $classFrame.entry -side left label $sectionFrame.label -text "Section" -width 20 entry $sectionFrame.entry -textvariable gClassl($num.editsection) -width 3 \ -validate key -validatecommand "limitEntry %W 3 number %P" pack $sectionFrame.label $sectionFrame.entry -side left label $stuFrame.label -text "Student Number" -width 20 entry $stuFrame.entry -textvariable gClassl($num.editstu) -width 9 \ -validate key -validatecommand "limitEntry %W 9 any %P" pack $stuFrame.label $stuFrame.entry -side left label $nameFrame.label -text "Name(Last, First MI)" -width 20 entry $nameFrame.entry -textvariable gClassl($num.editname) -width 30 \ -validate key -validatecommand "limitEntry %W 30 any %P" pack $nameFrame.label $nameFrame.entry -side left label $emailFrame.label -text "Email" -width 20 entry $emailFrame.entry -textvariable gClassl($num.editemail) -width 40 \ -validate key -validatecommand "limitEntry %W 40 any %P" pack $emailFrame.label $emailFrame.entry -side left button $buttonFrame.add -text $buttonname -command "set gClassl($num.done) 1" button $buttonFrame.cancel -text Cancel -command "set gClassl($num.done) 0" pack $buttonFrame.add $buttonFrame.cancel -side left bind $add "set gClassl($num.done) 1" Centre_Dialog $add default update focus $add capaGrab $add return 0 } ########################################################### # classlDelete ########################################################### ########################################################### ########################################################### proc classlDelete { num } { global gClassl gWindowMenu if { [set which [$gClassl($num) curselection]] == "" } { displayMessage "Select a student first" return } $gClassl($num) delete $which set gClassl($num.changed) 1 } ########################################################### # classlEdit ########################################################### ########################################################### ########################################################### proc classlEdit { num } { global gClassl gWindowMenu if { [set which [$gClassl($num) curselection]] == "" } { displayMessage "Select a student first" return } set record [$gClassl($num) get $which] set gClassl($num.editclass) [string trimright [string range $record 0 8]] set gClassl($num.editsection) [string trimright [string range $record 10 12]] set gClassl($num.editstu) [string trimright [string range $record 14 22]] set gClassl($num.editname) [string trimright [string range $record 24 53]] set gClassl($num.editemail) [string trimright [string range $record 60 99]] if { [makeClasslEntryEditor $num ".classledit$num" "Editing Student" "Done"] } { return } vwait gClassl($num.done) capaGrab release .classledit$num destroy .classledit$num if { $gClassl($num.done) } { set gClassl($num.editsection) [string trimleft $gClassl($num.editsection) "0"] set record [format "%-9s %03d %-9s %-30s %-40s" $gClassl($num.editclass) \ $gClassl($num.editsection) $gClassl($num.editstu) \ $gClassl($num.editname) $gClassl($num.editemail)] $gClassl($num) delete $which $gClassl($num) insert $which $record set gClassl($num.changed) 1 } } ########################################################### # findStuNumClassl ########################################################### ########################################################### ########################################################### proc findStuNumClassl { num newstunum } { global gClassl set max [$gClassl($num) index end] for {set i 0} {$i < $max} {incr i} { set teststunum [string range [$gClassl($num) get $i] 14 22] if { [regexp -nocase $newstunum $teststunum] } { return $i } } return -1 } ########################################################### # classlAdd ########################################################### ########################################################### ########################################################### proc classlAdd { num } { global gClassl gWindowMenu set gClassl($num.editclass) "" set gClassl($num.editsection) "" set gClassl($num.editstu) "" set gClassl($num.editname) "" set gClassl($num.editemail) "" if { [makeClasslEntryEditor $num ".classladd$num" "Adding a Student" "Add"] } { return } vwait gClassl($num.done) capaGrab release .classladd$num destroy .classladd$num if { $gClassl($num.done) } { if { [set which [findStuNumClassl $num $gClassl($num.editstu)]] > -1 } { if { "Cancel" == [makeSure "Found a duplicate student \n [$gClassl($num) get $which] \n Replace this one?"] } { set gClassl($num.done) 0 displayMessage "Student was not added." } else { $gClassl($num) delete $which } } } if { $gClassl($num.done) } { set gClassl($num.editsection) [string trimleft $gClassl($num.editsection) "0"] set a [format "%-9s %03d %-9s %-30s %-40s" $gClassl($num.editclass) \ $gClassl($num.editsection) $gClassl($num.editstu) \ $gClassl($num.editname) $gClassl($num.editemail)] $gClassl($num) insert 0 $a set gClassl($num.changed) 1 } } ########################################################### # classlPrint ########################################################### ########################################################### ########################################################### proc classlPrint { num } { global gClassl gWindowMenu gFile if { [set which [$gClassl($num) curselection]] == "" } { displayMessage "Select a student first" return } if { $gClassl($num.changed) == 1 } { if {[askToSave "Do you wish to save $gFile($num)?" "saveClassl $num"]=="Yes"} { saveClassl $num } } set record [$gClassl($num) get $which] set stunum [string range $record 14 22] if { [winfo exists .capaprint$num] } { capaRaise .capaprint$num return 1 } set print [toplevel .capaprint$num] $gWindowMenu add command -label "Printing a Student" -command "capaRaise $print" wm title $print "Printing a Student" set infoFrame [frame $print.info] set dataFrame [frame $print.data] set buttonFrame [frame $print.button] pack $infoFrame $dataFrame $buttonFrame -side top -anchor w label $infoFrame.label -text "Print For Student $stunum" pack $infoFrame.label set setFrame [frame $dataFrame.set] set printerFrame [frame $dataFrame.printer] pack $setFrame $printerFrame -side top -anchor w label $setFrame.label -text "Set" -width 13 entry $setFrame.set -textvariable gClassl($num.printset) -width 2 \ -validate key -validatecommand "limitEntry %W 9 any %P" pack $setFrame.label $setFrame.set -side left label $printerFrame.label -text "Printer Name" -width 13 entry $printerFrame.printer -textvariable gClassl($num.printername) -width 20 pack $printerFrame.label $printerFrame.printer -side left button $buttonFrame.print -text "Print" -command "set gClassl($num.done) 1" button $buttonFrame.cancel -text "Cancel" -command "set gClassl($num.done) 0" pack $buttonFrame.print $buttonFrame.cancel -side left bind $print "set gClassl($num.done) 1" Centre_Dialog $print default update focus $print capaGrab $print vwait gClassl($num.done) capaGrab release $print if { $gClassl($num.done) } { global gCapaConfig parseCapaConfig $num [file dirname $gFile($num)] if {[catch {printStudent $num $stunum $gClassl($num.printset) $gClassl($num.printername)} error ]} { displayError "Unable to print $stunum" } foreach name [array names gCapaConfig "$num.*"] { unset gCapaConfig($name) } } destroy $print } ########################################################### # printStudent ########################################################### ########################################################### ########################################################### proc printStudent { num stunum printset printername } { global gCapaConfig gFile set command "$gCapaConfig($num.qzparse_command) -c [file dirname $gFile($num)] \ -set $printset -stu $stunum" eval "exec $command" set tex_file [file join [file dirname $gFile($num)] TeX $stunum.tex] set command "$gCapaConfig($num.latex_command) $tex_file" removeStatus $num #if { "Yes" != [makeSure "Planning on running LaTeX, Continue?"] } { return } displayStatus "Running LaTeX" message $num set directory [pwd] cd [file join [file dirname $gFile($num)] TeX] eval "exec $command" cd $directory set dvi_file [file join [file dirname $gFile($num)] TeX $stunum.dvi] set ps_file [file join [file dirname $gFile($num)] TeX $stunum.ps] set command "$gCapaConfig($num.dvips_command) $dvi_file -o $ps_file >& /dev/null" removeStatus $num #if { "Yes" != [makeSure "Planning on running dvips, Continue?"] } { return } displayStatus "Running dvips" message $num eval "exec $command" removeStatus $num #if { "Cancel" == [set lprcmd [getLprCommand $ps_file $num]] } { return } if { [catch { eval "exec lpr -P$printername $ps_file" } errors ] } { displayError "An error occurred while printing: $errors" } } ########################################################### # updateClasslStatus ########################################################### ########################################################### ########################################################### proc updateClasslStatus { name1 name2 op } { global gClassl gWindowMenu set num [lindex [split $name2 .] 0] if { $gClassl($num.changed) != $gClassl($num.changedlast)} { set gClassl($num.changedlast) $gClassl($num.changed) global gFile if { ![winfo exists $gClassl($num)] } { return } if { $gClassl($num.changed) } { catch {removeWindowEntry "Classl $gFile($num)*"} wm title [winfo toplevel $gClassl($num)] "Classl $gFile($num) (Modified)" $gWindowMenu add command -label "Classl $gFile($num) (Modified)" -command \ "capaRaise $gClassl($num)" } else { catch {removeWindowEntry "Classl $gFile($num)*"} wm title [winfo toplevel $gClassl($num)] "Classl $gFile($num)" $gWindowMenu add command -label "Classl $gFile($num)" -command \ "capaRaise $gClassl($num)" } } } ########################################################### # classlCopy ########################################################### ########################################################### ########################################################### proc classlCopy { num field } { global gClassl if { ![winfo exists $gClassl($num)] } { return } if { [set which [$gClassl($num) curselection]] == "" } { displayMessage "Select a student first" return } set entry [$gClassl($num) get $which] set text "" switch $field { stunum { set text [string trimright [string range $entry 14 22]] } name { set text [string trimright [string range $entry 24 53]] } email { set text [string trimright [string range $entry 60 99]] } } if { $text != "" } { set gClassl($num.selection) $text selection own $gClassl($num) selection handle $gClassl($num) "classlPaste $num" selection handle -selection CLIPBOARD $gClassl($num) "classlPaste $num" clipboard clear -displayof $gClassl($num) clipboard append -displayof $gClassl($num) -- $text } } ########################################################### # classlPaste ########################################################### ########################################################### ########################################################### proc classlPaste { num start length } { global gClassl return [string range $gClassl($num.selection) $start [expr $start + $length]] } ########################################################### # classlFind ########################################################### ########################################################### ########################################################### proc classlFind { num } { global gClassl gWindowMenu if { [winfo exists .classlfind$num] } { capaRaise .classlfind$num return } set classlFind [toplevel .classlfind$num] $gWindowMenu add command -label "Find in Classl" \ -command "capaRaise $classlFind" wm title $classlFind "Find" set infoFrame [frame $classlFind.info] set entryFrame [frame $classlFind.entry] set buttonFrame [frame $classlFind.button] pack $infoFrame $entryFrame $buttonFrame -side top -anchor w set nameFrame [frame $entryFrame.name] set stunumFrame [frame $entryFrame.stunum] set emailFrame [frame $entryFrame.email] pack $nameFrame $stunumFrame $emailFrame -side top -anchor w label $nameFrame.label -text "Name" -width 14 -anchor w entry $nameFrame.name -textvariable gClassl($num.findname) -width 30 \ -validate key -validatecommand "limitEntry %W 30 any %P" frame $nameFrame.spacer -width 80 button $nameFrame.go -text "Find" -command "classlDoFind $num name" pack $nameFrame.label $nameFrame.name $nameFrame.spacer $nameFrame.go \ -side left -anchor w label $stunumFrame.label -text "Student Number" -width 14 -anchor w entry $stunumFrame.stunum -textvariable gClassl($num.findstunum) -width 9 \ -validate key -validatecommand "limitEntry %W 9 any %P" frame $stunumFrame.spacer -width 248 button $stunumFrame.go -text "Find" -command "classlDoFind $num stunum" pack $stunumFrame.label $stunumFrame.stunum $stunumFrame.spacer \ $stunumFrame.go -side left -anchor w label $emailFrame.label -text "Email" -width 14 -anchor w entry $emailFrame.email -textvariable gClassl($num.findemail) -width 40 \ -validate key -validatecommand "limitEntry %W 40 any %P" button $emailFrame.go -text "Find" -command "classlDoFind $num email" pack $emailFrame.label $emailFrame.email $emailFrame.go -side left -anchor w button $buttonFrame.close -text "Close" -command "destroy $classlFind" pack $buttonFrame.close Centre_Dialog $classlFind default } ########################################################### # classlDoFind ########################################################### ########################################################### ########################################################### proc classlDoFind { num type } { global gClassl if {![winfo exists $gClassl($num)]} {return} if { [set which [$gClassl($num) curselection]] == "" } { set which 0 } else { incr which } set max [$gClassl($num) index end] for {set i 0} { $i < ($max)} {incr i} { set current [expr ($i+$which)%$max] set entry [$gClassl($num) get $current] switch $type { name { set tmp [string range [$gClassl($num) get $current] 24 53] } stunum { set tmp [string range [$gClassl($num) get $current] 14 22] } email { set tmp [string range [$gClassl($num) get $current] 60 99] } } if { [regexp -nocase $gClassl($num.find$type) $tmp] } { $gClassl($num) selection clear 0 end $gClassl($num) selection set $current $gClassl($num) see $current return } } displayMessage "Not Found" } ########################################################### # classlMerge ########################################################### ########################################################### ########################################################### proc classlMerge { num } { global gClassl set filename [tk_getOpenFile -title "Select a File to merge in"] if { $filename == "" } { return } set fileId [open $filename "r"] set maxlines [lindex [exec wc -l $filename] 0] set linenum 0 set newentries 0 displayStatus "Merging $filename" both $num set aline [gets $fileId] while {![eof $fileId]} { incr linenum set found 0 set stunum [string range $aline 14 22] set max [$gClassl($num) index end] for {set i 0} { $i < ($max)} {incr i} { set tmp [string range [$gClassl($num) get $i] 14 22] if { [regexp -nocase $stunum $tmp] } { set found 1 break } } if { !$found } { incr newentries $gClassl($num) insert end $aline } updateStatusBar [expr $linenum/double($maxlines)] $num set aline [gets $fileId] } removeStatus $num if { $newentries != 0 } { $gClassl($num) see $max $gClassl($num) selection set $max } displayMessage "Added $newentries students." }