1: ###########################################################
2: # quizzer.tcl -
3: # Copyright Guy Albertelli II 1996
4: ###########################################################
5: set gTclVer 4.0
6:
7: ###########################################################
8: # createControlWindow
9: ###########################################################
10: # Creates the menu window
11: ###########################################################
12: # Arguments: none
13: # Returns: nothing
14: ###########################################################
15: proc createControlWindow {} {
16: global gPrefs gDate gFind gChanged gWindowMenu gStudentSelection gFile \
17: gUniqueNumber gXdviOpt gHeaderQCount gDir gHintVal gTryVal gProbVal \
18: gPutLine gQuizTemp gCapaConfig gStopPrinting gFindList gFirstTime \
19: gRefChanged gChangedLast gCreateImportLinks gFasterParsing
20:
21: after 500 { dateUpdate }
22: after 1000 { cleanWindowList }
23:
24: set gFasterParsing 1
25: set gFirstTime 1
26: set gPrefs(info) "Problem"
27: set gPrefs(TeXHeader) ""
28: set gPrefs(TeXFooter) ""
29: set gFind(find) ""
30: set gFind(replace) ""
31: set gFind(findOption) "-nocase"
32: set gFind(scope) File
33: set gChanged 0
34: set gChangedLast 0
35: trace variable gChanged w updateChangeStatus
36: trace variable gRefChanged w updateChangeStatus
37: set gStudentSelection(type) "Random"
38: set gStudentSelection(random) "1"
39: set gStudentSelection(studentNumber) ""
40: set gStudentSelection(studentName) ""
41: set gFile ""
42: set gUniqueNumber 1
43: set gXdviOpt "-geometry 800x650"
44: set gHeaderQCount 0
45: set gPutLine 1
46: set gTryVal 99
47: set gHintVal 1
48: set gProbVal 1
49: set gStopPrinting 0
50: set gDir(class) [pwd]
51: set gDir(import) [pwd]
52: set gDir(include) [pwd]
53: set gDir(reference) [pwd]
54: set gQuizTemp "true"
55: set gFindList(files) ""
56: set gFindList(refNum) ""
57: set gCreateImportLinks 1
58: set gCapaConfig(IMP_color) #0000ff
59: set gCapaConfig(comment_color) #008400
60: set gCapaConfig(Printer_selected) "0"
61: set gCapaConfig(latex_command) "latex"
62: set gCapaConfig(qzparse_command) "qzparse"
63: set gCapaConfig(dvips_command) "dvips"
64: set gCapaConfig(xdvi_command) "xdvi"
65: set gCapaConfig(lprOneSided_command) "lpr "
66: set gCapaConfig(lprTwoSided_command) ""
67: set gCapaConfig(printer_option) ""
68: set gCapaConfig(standardQuizzerHeader) "//CAPA system software is copyrighted by Michigan State University.\n//By using these materials, the User agrees to:\n//1) Protect the source code files from unauthorized copying.\n//2) Limit access of the source material to teaching staff.\n//3) The User is free to mix, cut and paste, modify, adapt, delete,\n// improve, etc. the problems and graphics for his/her own use.\n//\n/IMP \"../Tools/StdMacros\"\n/IMP \"../Tools/StdUnits\"\n/IMP \"../Tools/StdConst\"\n/IMP \"HWTop\"\n"
69:
70:
71: wm withdraw .
72:
73: # there is code later on that depends upon .main existing and being visable
74: set menuFrame [menu .main -tearoff 0 -type tearoff ]
75:
76: wm title $menuFrame "Quizzer"
77:
78: $menuFrame post 0 0
79:
80: wm geometry $menuFrame "+0+20"
81: $menuFrame add command -label "Quizzer" -foreground grey85 -background \
82: black -state disabled
83: $menuFrame add command -label "Info" -command { createInfoWindow }
84: $menuFrame add cascade -label "File" -menu $menuFrame.file
85: #$menuFrame add cascade -label "Edit .qz" -menu $menuFrame.edit
86: #$menuFrame add cascade -label "Find" -menu $menuFrame.find
87: $menuFrame add command -label "Prefs" -command { createPrefsWindow }
88: $menuFrame add cascade -label "Windows" -menu $menuFrame.windows
89: $menuFrame add command -label "Create .dvi" -command {
90: studentSelectWindow createDvi } -accelerator "Alt+D"
91: bind all <Alt-Shift-D> "studentSelectWindow createDvi"
92: $menuFrame add command -label "Analyze Set" -command {
93: analyzeSet } -accelerator "Alt+A"
94: bind all <Alt-Shift-A> "analyzeSet"
95: $menuFrame add command -label "Print" -command { printWindow }
96: $menuFrame add command -label "Remap" -command { createRemapWindow }
97: $menuFrame add command -label "Xdvi Options" -command { createXdviOpt }
98: #$menuFrame add command -label "Change font" -command { changeFont }
99: $menuFrame add command -label "Quit" -command { quit } \
100: -accelerator "Alt+q"
101: bind all <Alt-q> quit
102: bind $menuFrame <Destroy> "quit 1"
103:
104: set file [menu $menuFrame.file -tearoff 1 ]
105: set edit [menu $menuFrame.edit -tearoff 1 ]
106: #set find [menu $menuFrame.find -tearoff 1 ]
107: set windows [menu $menuFrame.windows -tearoff 1 ]
108: set gWindowMenu $windows
109:
110: $file add command -label "Set.qz File" -foreground grey50 -background \
111: black -state disabled
112: $file add command -label "New" -command {
113: createEditingWindow
114: pickCapaConfig
115: } -accelerator "Alt+n"
116: bind all <Alt-n> {
117: createEditingWindow
118: pickCapaConfig
119: }
120: $file add command -label "Open" -command { openDocument } -accelerator "Alt+o"
121: bind all <Alt-o> openDocument
122: $file add command -label "Save" -command { saveDocument } -accelerator "Alt+s"
123: # binding moved to the creation of the editwindow
124: # bind $menuFrame <Alt-s> saveDocument
125: $file add command -label "Save As..." -command { saveDocument 1 } \
126: -accelerator "Alt+S"
127: # binding moved to the creation of the editwindow
128: # bind $menuFrame <Alt-Shift-s> { saveDocument 1 }
129: $file add command -label "Delete" -command { deleteFile 0 }
130: $file add command -label "Close" -command { closeDocument } -accelerator "Alt+w"
131: # binding moved to the creation of the editwindow
132: # bind .main <Alt-w> closeDocument
133: $file add command -label "Reference File" -foreground grey90 -background \
134: black -state disabled
135: $file add command -label "New Reference File..." \
136: -command { newReferenceFile } -accelerator "Alt+t"
137: bind all <Alt-t> openReferenceFile
138: $file add command -label "Open Reference File..." \
139: -command { openReferenceFile } -accelerator "Alt+r"
140: bind all <Alt-r> openReferenceFile
141: $file add command -label "Open capa.config" \
142: -command { openReferenceFile capa.config }
143:
144: $edit add command -label "Cut" -command { cut } -accelerator "Alt+x"
145: # binding moved to the creation of the editwindow
146: # bind $menuFrame <Alt-x> cut
147: $edit add command -label "Copy" -command { copy } -accelerator "Alt+c"
148: # binding moved to the creation of the editwindow
149: # bind $menuFrame <Alt-c> copy
150: $edit add command -label "Paste" -command { paste } -accelerator "Alt+v"
151: # binding moved to the creation of the editwindow
152: # bind .main <Alt-v> paste
153: $edit add command -label "Select All " -command { selectAll } \
154: -accelerator "Alt+a"
155: # binding moved to the creation of the editwindow
156: # bind $menuFrame <Alt-a> selectAll
157: $edit add separator
158: $edit add command -label "Undo" -command "undo 0" \
159: -accelerator "Alt+u"
160: # $edit add command -label "Redo" -command "redo $num"
161: $edit add separator
162: $edit add command -label "Find" -command { createFindWindow } \
163: -accelerator "Alt+f"
164: bind all <Alt-f> createFindWindow
165:
166: # $find add command -label "Find Panel.." -command { createFindWindow } \
167: -accelerator "Alt+f"
168: # bind all <Alt-f> createFindWindow
169: # $find add command -label "Find Next" -command { next }
170: # $find add command -label "Find Previous" -command { previous }
171: # $find add command -label "Enter Selecton" -command { enterSelection }
172: # $find add command -label "Jump to Selection" -command { jumpToSelection }
173: # $find add command -label "Line Range..." -command { createLineWindow } \
174: -accelerator "Alt+l"
175: # bind all <Alt-l> createLineWindow
176:
177: bind all <Alt-0> printInfo
178: bind all <Alt-KeyPress> { #unbind tkTraverseToMenu
179: }
180: bind all <Control-Tab> {tkTabToWindow [tk_focusPrev %W]}
181: catch {bind all <ISO_Left_Tab> {tkTabToWindow [tk_focusPrev %W]}}
182: catch {bind all <KP_Tab> {tkTabToWindow [tk_focusPrev %W]}}
183: trace variable gQuizTemp w "changeMenuStatus $menuFrame"
184: }
185:
186: ###########################################################
187: # changeMenuStatus
188: ###########################################################
189: # either enables or disable printing or creation of Dvi files
190: # based on the value of the gQuizTemp global
191: ###########################################################
192: # Argument: menuFrame (path name of the menu window)
193: # name1 (name of traced varaiable, gQuizTemp)
194: # name2 (empty argument from trace)
195: # op (tracing on writes so this should be "w")
196: # Returns : nothing
197: # Globals : gQuizTemp (r)
198: ###########################################################
199: proc changeMenuStatus { menuFrame name1 name2 op } {
200: global gQuizTemp
201: if { $gQuizTemp } {
202: $menuFrame entryconfigure 5 -state normal
203: $menuFrame entryconfigure 6 -state normal
204: } else {
205: $menuFrame entryconfigure 5 -state disabled
206: $menuFrame entryconfigure 6 -state disabled
207: }
208: }
209:
210: ###########################################################
211: # printInfo
212: ###########################################################
213: # gets called by Alt-0, used to print out variable while
214: # still running
215: ###########################################################
216: # Argument: none
217: # Returns : nothing
218: # Globals : auto_path
219: ###########################################################
220: proc printInfo { } {
221: global auto_path gUndo gRefText
222: set num [lindex [array names gRefText] 0]
223: set a "updateLocation 0"
224: puts [list Main2: [time $a 20000]]
225: set a "updateLocation $num"
226: puts [list Ref : [time $a 20000]]
227: }
228:
229: ###########################################################
230: # createXdviOpt
231: ###########################################################
232: ###########################################################
233: ###########################################################
234: proc createXdviOpt {} {
235: global gXdviOpt gWindowMenu
236:
237: if { [winfo exists .xdviOpt] } {
238: capaRaise .xdviOpt
239: return
240: }
241:
242: set xdviOpt [toplevel .xdviOpt]
243: $gWindowMenu add command -label "XdviOptions" -command "capaRaise $xdviOpt"
244: wm title $xdviOpt "Options for Xdvi"
245:
246: set messageFrame [frame $xdviOpt.msg]
247: message $xdviOpt.msg2 -text "Example: -geometry 800x700" -aspect 5000
248: set buttonFrame [frame $xdviOpt.buttons -bd 10]
249: pack $messageFrame $xdviOpt.msg2 $buttonFrame -side top -fill x
250:
251: message $messageFrame.msg -text "Options to xdvi:" -aspect 5000
252: entry $messageFrame.entry -textvariable gXdviOpt
253:
254: pack $messageFrame.msg $messageFrame.entry -side left -fill x
255:
256: button $buttonFrame.ok -text Dismiss -command "destroy $xdviOpt
257: removeWindowEntry XdviOptions" -underline 0
258: pack $buttonFrame.ok -side left
259: bind $xdviOpt <Destroy> "removeWindowEntry XdviOptions"
260: }
261:
262: ###########################################################
263: # createInfoWindow
264: ###########################################################
265: # creates the Information window
266: ###########################################################
267: # Arguments: None
268: # Returns: Nothing
269: # Globals: gDate - the variable containg the current date
270: # gWindowMenu - used to register the new window in the
271: # windows menu
272: # gVer - Stores the current version of Quizzer (set in
273: # C init code
274: ###########################################################
275: proc createInfoWindow {} {
276: global gDate gWindowMenu gVer gTclVer gCmd gCompileDate gUndoSize gUniqueNumber
277:
278: if { [winfo exists .about] } {
279: capaRaise .about
280: return
281: }
282:
283: set about [toplevel .about]
284: $gWindowMenu add command -label "About" -command "capaRaise $about"
285: wm title $about "About"
286:
287: label $about.l1 -font 12x24 -text "Quizzer $gVer" -pady 20
288: label $about.l4 -font 8x13 -text "Quizzer.tcl version $gTclVer" -pady 20
289: label $about.l6 -font 8x13 -text "$gCompileDate"
290: message $about.l2 -font 8x13 -text "Code by: Y. Tsai, G. Albertelli II Copyright Michigan State University Board of Trustees, 1992-1999, No Unauthorized Commercial Use" \
291: -pady 20 -aspect 300
292: label $about.l3 -font 8x13 -textvariable gDate
293: label $about.l5 -font 8x13 -textvariable gCmd
294: label $about.l7 -font 8x13 -textvariable gUndoSize
295: label $about.l8 -font 8x13 -textvariable gUniqueNumber
296:
297: button $about.close -text "Close" -command "destroy $about
298: removeWindowEntry About"
299:
300: pack $about.l1 $about.l4 $about.l6 $about.l2 $about.l3 $about.l5 $about.l7 $about.l8\
301: $about.close -side top
302: bind $about <Destroy> "removeWindowEntry About"
303: Centre_Dialog $about default
304: }
305:
306: ###########################################################
307: # enterSelection
308: ###########################################################
309: ###########################################################
310: ###########################################################
311: proc enterSelection {} {
312: global gTextWindow gFind
313: if { [catch {set gTextWindow}] } { return }
314: if { ![winfo exists $gTextWindow] } { return }
315:
316: createFindWindow
317: catch {set gFind(find) [$gTextWindow get sel.first sel.last]}
318: }
319:
320: ###########################################################
321: # jumpToSelection
322: ###########################################################
323: ###########################################################
324: ###########################################################
325: proc jumpToSelection {} {
326: global gTextWindow
327: catch {$gTextWindow see sel.first}
328: }
329:
330: proc cut {} {global gTextWindow;tk_textCut $gTextWindow}
331: proc copy {} {global gTextWindow;tk_textCopy $gTextWindow}
332: proc paste {} {global gTextWindow;tk_textPaste $gTextWindow}
333:
334: ###########################################################
335: # selectAll
336: ###########################################################
337: ###########################################################
338: ###########################################################
339: proc selectAll { { refNum 0 } } {
340: global gTextWindow gRefText
341:
342: if { $refNum } { set window $gRefText($refNum) } else {
343: catch {set window $gTextWindow}
344: }
345: if { ![winfo exists $window] } { return }
346: $window tag add sel 0.0 end
347: }
348:
349: ###########################################################
350: # creatEditingWindow
351: ###########################################################
352: ###########################################################
353: # Arguments: none
354: # Returns: a one if the Editing window existed and a zero
355: # if it created a new window
356: # Globals:
357: ###########################################################
358: proc createEditingWindow { {setupUndo 1} } {
359: global gEditWindow gPreviewMode gTextWindow gSetNumberText gFile \
360: gWindowMenu gNumberParsedText gLineNumberGoto gUndo \
361: gCharacterNumberGoto gLineNumberGoto gClosedDocument \
362: gPreviewButton gFirstTime
363:
364: if { [winfo exists .editwindow] } {
365: capaRaise .editwindow
366: return 1
367: }
368: set gFirstTime 1
369:
370: set gEditWindow [toplevel .editwindow]
371: $gWindowMenu add command -label "$gFile" -command "capaRaise $gEditWindow"
372: wm title $gEditWindow $gFile
373: set gClosedDocument 0
374: set editWindow [frame $gEditWindow.frame -borderwidth 10]
375:
376: pack $editWindow -expand 1 -fill both
377:
378: set editTop [frame $editWindow.editTop]
379: set editBottom [frame $editWindow.editBottom]
380:
381: pack $editTop $editBottom -side top
382: pack configure $editBottom -expand 1 -fill both
383:
384: set menuFrame [frame $editTop.menu -borderwidth 2 -relief raised]
385: set assignInfo [frame $editTop.assignInfo -borderwidth 4 -relief groove]
386: set mode [frame $editTop.mode -borderwidth 4 -relief groove]
387: set buttonAndGoto [frame $editTop.buttonAndGoto ]
388: pack $menuFrame $assignInfo $mode $buttonAndGoto -side left
389: pack configure $menuFrame -anchor n
390:
391: menubutton $menuFrame.edit -text Edit -menu $menuFrame.edit.m
392: pack $menuFrame.edit -side left
393:
394: set edit [ menu $menuFrame.edit.m ]
395: $edit add command -label "Cut" -command { cut } -accelerator "Alt+x"
396: $edit add command -label "Copy" -command { copy } -accelerator "Alt+c"
397: $edit add command -label "Paste" -command { paste } -accelerator "Alt+v"
398: $edit add command -label "Select All " -command { selectAll } -accelerator "Alt+a"
399: $edit add separator
400: $edit add command -label "Undo" -command "undo 0" -accelerator "Alt+u"
401: $edit add separator
402: $edit add command -label "Find" -command { createFindWindow } -accelerator "Alt+f"
403: bind all <Alt-f> createFindWindow
404:
405: set buttons [frame $buttonAndGoto.buttons ]
406: set gotoFrame [ frame $buttonAndGoto.gotoFrame ]
407: pack $buttons $gotoFrame -side top
408:
409: set button1 [frame $buttons.button1]
410: set button2 [frame $buttons.button2]
411: pack $button1 $button2 -side top
412:
413: set gPreviewButton [button $button1.preview -text "Preview" -command \
414: { studentSelectWindow createPreviewWindow }]
415: button $button1.dbHeader -text "DB Header" -command createDBHeader
416: button $button1.include -text "Include" -command includeFile
417: pack $button1.preview $button1.dbHeader $button1.include -side left
418:
419: button $button2.header -text "Std. Header" \
420: -command insertStandardHeader
421: button $button2.import -text "Import" -command importFile
422: button $button2.end -text "Endline" -command insertEndline
423: pack $button2.header $button2.import $button2.end -side left
424:
425: label $gotoFrame.msg -text "Current Line:"
426: label $gotoFrame.current -textvariable gLineNumber
427: entry $gotoFrame.line -width 8 -textvariable gLineNumberGoto
428: bind $gotoFrame.line <KeyPress-Return> "gotoLine"
429: button $gotoFrame.button -text "Goto" -command "gotoLine"
430: pack $gotoFrame.msg $gotoFrame.current $gotoFrame.line \
431: $gotoFrame.button -side left
432: # variable used by gotoLine, needs to be set if it doesn't exist
433: if { [ catch { set gCharacterNumberGoto } ] } {
434: set gCharacterNumberGoto ""
435: }
436:
437: label $assignInfo.time -textvariable gDate
438: set setNum [frame $assignInfo.setNum -borderwidth 2]
439: set probsParsed [frame $assignInfo.probsParsed -borderwidth 2]
440:
441: pack $assignInfo.time $setNum $probsParsed -side top
442: pack configure $setNum $probsParsed -anchor e
443:
444: message $setNum.msg -text "Problem Set Number" -aspect 10000
445: set setNumberWindow [message $setNum.num -relief sunken -width 70 \
446: -textvariable gSetNumberText]
447:
448: pack $setNum.num $setNum.msg -side right -anchor e
449:
450: label $probsParsed.msg -text "Number of Questions Parsed"
451: set numberParsedWindow [label $probsParsed.num -relief sunken \
452: -textvariable gNumberParsedText]
453:
454: pack $probsParsed.num $probsParsed.msg -side right -anchor e
455:
456: message $mode.msg -text "Mode" -aspect 10000
457: radiobutton $mode.enscript -text "Enscript" -value "Enscript" \
458: -variable gPreviewMode
459: radiobutton $mode.tex -text "TeX" -value "TeX" -variable gPreviewMode
460: radiobutton $mode.web -text "Web" -value "Web" -variable gPreviewMode
461:
462: pack $mode.msg $mode.enscript $mode.tex $mode.web -side top
463: pack configure $mode.enscript $mode.tex $mode.web -anchor w
464: set gPreviewMode Enscript
465:
466: scrollbar $editBottom.scroll -orient vertical -command \
467: "$editBottom.text yview"
468: set gTextWindow [text $editBottom.text -yscrollcommand \
469: "$editBottom.scroll set" -wrap char -height 40]
470:
471: pack $editBottom.scroll $editBottom.text -side left -expand 0
472: pack configure $editBottom.scroll -expand 0 -fill y
473: pack configure $editBottom.text -expand true -fill both
474:
475: if { $setupUndo} {
476: rename $gTextWindow .$gTextWindow
477: trackChanges $gTextWindow 0
478: set gUndo(0) 0
479: set gUndo(0.cur) 0
480: }
481:
482: bind $gTextWindow <Alt-s> saveDocument
483: bind $gTextWindow <Alt-Shift-s> { saveDocument 1 }
484: bind $gEditWindow <Alt-w> closeDocument
485: # bind $gEditWindow <Destroy> "closeDocument 1"
486: wm protocol $gEditWindow WM_DELETE_WINDOW "closeDocument 1"
487: bind $gTextWindow <Alt-x> "tk_textCut %W"
488: bind $gTextWindow <Alt-c> "tk_textCopy %W"
489: bind $gTextWindow <Alt-v> "tk_textPaste %W"
490: bind $gTextWindow <Alt-a> selectAll
491: bind $gTextWindow <Alt-u> "undo 0"
492: addFindList
493: Centre_Dialog $gEditWindow default
494:
495: createImportLinks 0 0.0 end
496: return 0
497: }
498:
499: ###########################################################
500: # includeFile
501: ###########################################################
502: ###########################################################
503: ###########################################################
504: proc includeFile {} {
505: global gTextWindow gDir
506:
507: if { [makeSure "Is the cursor in the correct position?"] == "Cancel" } {
508: return
509: }
510:
511: # if { $gDir(include) == "." } { set gDir(include) [pwd] }
512: set file [tk_getOpenFile -filetypes \
513: { { {All Files} {"*"} } { {Quizzer} {"*.qz"} } } \
514: -title "Select the proper file" \
515: -initialdir "$gDir(include)" ]
516: if { $file == "" } { return }
517: set gDir(include) [file dirname $file]
518:
519: if { $file == "" } { return }
520:
521: set fileId [open $file "r"]
522:
523: $gTextWindow insert insert [read $fileId [file size $file]]
524: }
525:
526: ###########################################################
527: # insertStandardHeader
528: ###########################################################
529: ###########################################################
530: ###########################################################
531: proc insertStandardHeader {} {
532: global gTextWindow gCapaConfig
533:
534: if { [makeSure "Is the cursor in the correct position?"] == "Cancel" } {
535: return
536: }
537: $gTextWindow insert insert $gCapaConfig(standardQuizzerHeader)
538: }
539:
540: ###########################################################
541: # importFile
542: ###########################################################
543: ###########################################################
544: ###########################################################
545: proc importFile {} {
546: global gTextWindow gDir gProbVal gTryVal gHintVal gPutLine
547:
548: if { [makeSure "Is the cursor in the correct position?"] == "Cancel" } {
549: return
550: }
551:
552: # if { $gDir(import) == "." } { set gDir(import) [pwd] }
553: set file [tk_getOpenFile -filetypes \
554: { { {All Files} {"*"} } { {Quizzer} {"*.qz"} } } \
555: -title "Select the proper file" -initialdir "$gDir(import)" ]
556: if { $file == "" } { return }
557: set gDir(import) [file dirname $file]
558:
559:
560: if { [getProbValTryVal] == "Cancel" } { return }
561:
562: $gTextWindow insert insert "//\n/BEG prob_val=$gProbVal\n/LET try_val=$gTryVal\n/LET hint_val=$gHintVal\n/DIS(\"$file\")\n/IMP \"$file\"\n"
563: if { $gPutLine } {
564: $gTextWindow insert insert "/DIS(stdline)\n"
565: } else {
566: $gTextWindow insert insert "/DIS(webonlyline)\n"
567: }
568: $gTextWindow see insert
569: }
570:
571: ###########################################################
572: # insertEndline
573: ###########################################################
574: ###########################################################
575: ###########################################################
576: proc insertEndline {} {
577: global gTextWindow
578:
579: if { [makeSure "Is the cursor in the correct position?"] == "Cancel" } {
580: return
581: }
582: $gTextWindow insert insert "/END(stdendline)\n"
583: }
584:
585: ###########################################################
586: # getProbValTryVal
587: ###########################################################
588: ###########################################################
589: ###########################################################
590: proc getProbValTryVal {} {
591: global gPrompt gProbVal gTryVal gHintVal gPutLine
592:
593: set dialog [toplevel .getProbValTryVal -borderwidth 10]
594: wm title $dialog "Getting Problem Value and Try Value"
595: wm geo $dialog "+200+200"
596: message $dialog.msg -text "Set the weight of the problem and the number of tries allowed." -aspect 700
597:
598: set gPrompt(result) ""
599: scale $dialog.probVal -orient horizontal -variable gProbVal \
600: -from 0 -to 9 -label "Problem Value" -length 150
601: scale $dialog.tryVal -orient horizontal -variable gTryVal \
602: -from 0 -to 99 -label "Try Value" -length 150
603: scale $dialog.hintVal -orient horizontal -variable gHintVal \
604: -from 1 -to 99 -label "Number of Tries Before Showing Hint" -length 150
605: set gPrompt(stdline.1) "Put a stdline after this problem."
606: set gPrompt(stdline.0) "Put a webonlyline after this problem."
607: checkbutton $dialog.putLine -variable gPutLine \
608: -width 38 \
609: -textvariable gPrompt(displayLine) \
610: -command { set gPrompt(displayLine) $gPrompt(stdline.$gPutLine) }
611: set gPrompt(displayLine) $gPrompt(stdline.$gPutLine)
612: set buttonFrame [frame $dialog.buttons -bd 10]
613: pack $dialog.msg $dialog.probVal $dialog.tryVal $dialog.hintVal $dialog.putLine \
614: $buttonFrame -side top -fill x
615:
616: button $buttonFrame.yes -text Import -command {set gPrompt(yes) 1} \
617: -underline 0
618: button $buttonFrame.cancel -text Cancel -command { set gPrompt(yes) 0 } \
619: -underline 0
620: pack $buttonFrame.yes $buttonFrame.cancel -side left
621:
622: bind $dialog <Alt-Key> break
623: bind $dialog <Destroy> "set gPrompt(yes) 0"
624: Centre_Dialog $dialog default
625: update
626:
627: focus $dialog
628: capaRaise $dialog
629: capaGrab $dialog
630: vwait gPrompt(yes)
631: capaGrab release $dialog
632: bind $dialog <Destroy> ""
633: destroy $dialog
634: if {$gPrompt(yes)} {
635: return Done
636: } else {
637: return Cancel
638: }
639: }
640:
641: ###########################################################
642: # updateDateBox
643: ###########################################################
644: ###########################################################
645: ###########################################################
646: proc updateDateBox { listbox } {
647: global gControlDates
648: $listbox delete 0 end
649: for {set i 0} {$i < [llength $gControlDates]} {incr i } {
650: set date [lindex $gControlDates $i]
651: if { $i != 0 } {
652: $listbox insert end [eval format {"%4d %4d %s %s %s"} $date]
653: } else {
654: $listbox insert end [eval format {" DEFAULT %s %s %s"} [lrange $date 2 end]]
655: }
656: }
657: }
658:
659: ###########################################################
660: # loadDates
661: ###########################################################
662: ###########################################################
663: ###########################################################
664: proc loadDates { listbox } {
665: global gControlDates
666: if { [catch {getHeaderInfo}]} {
667: displayError "That set.db does not exist"
668: }
669: updateDateBox $listbox
670: }
671:
672: ###########################################################
673: # deleteDate
674: ###########################################################
675: ###########################################################
676: ###########################################################
677: proc deleteDate { listbox } {
678: global gControlDates
679: if { [set a [$listbox index anchor]] != 0 } {
680: catch {$listbox delete anchor}
681: set gControlDates [lreplace $gControlDates $a $a]
682: } else {
683: displayError "You can not delete the default setting, only change it."
684: }
685: }
686:
687: ###########################################################
688: # checkHeaderForDefault
689: ###########################################################
690: ###########################################################
691: ###########################################################
692: proc checkHeaderForDefault { } {
693: global gControlDates
694: if { [lindex [lindex $gControlDates 0] 0] == 0 && \
695: [lindex [lindex $gControlDates 0] 1] == 0 } {
696: return 1
697: }
698: return 0
699: }
700:
701: ###########################################################
702: # dueAnswerOrder
703: ###########################################################
704: ###########################################################
705: ###########################################################
706: proc dueAnswerOrder { } {
707: global gDates
708: set duetime [clock scan "$gDates(duemonth)/$gDates(dueday)/$gDates(dueyear) $gDates(duehour):$gDates(dueminute)"]
709: set answertime [clock scan "$gDates(answermonth)/$gDates(answerday)/$gDates(answeryear) $gDates(answerhour):$gDates(answerminute)"]
710: if { $duetime > $answertime } { return 1 } { return 0 }
711: }
712:
713: ###########################################################
714: # checkDateFields
715: ###########################################################
716: ###########################################################
717: ###########################################################
718: proc checkDateFields { } {
719: global gDates
720:
721: set result 1
722: foreach kind { open due answer } {
723: foreach type { year month day hour minute } {
724: if { [validate $kind $type] != 1 } {
725: return $kind$type
726: }
727: }
728: }
729: if { [validate "" durationhour] != 1 } { return durationhour }
730: if { [validate duration minute] != 1 } { return durationminute }
731: if { [catch { expr $gDates(sectionstart) }] } { return sectionstart } else {
732: if {[string length $gDates(sectionstart)] <1} { return sectionstart } else {
733: if { [catch { expr $gDates(sectionend) }] } { return sectionend } else {
734: if {[string length $gDates(sectionend)] <1} { return sectionend }
735: }
736: }
737: }
738: return $result
739: }
740:
741: ###########################################################
742: # validate
743: ###########################################################
744: ###########################################################
745: ###########################################################
746: proc validate { kind type {newvalue novalue} } {
747: global gDates
748: #tcl interprets all strings of digits with 0 as the first number as being
749: #in octal, need to prevent this from causing an error
750: if { $newvalue == "novalue" } {
751: set temp $gDates($kind$type)
752: set lowfail -1
753: } else {
754: if { $newvalue == "" } { return 1 }
755: set temp $newvalue
756: set lowfail 1
757: }
758: if { [string length $temp] > 1 && [string index $temp 0] == 0 } {
759: set test [string range $temp 1 end]
760: } else {
761: set test $temp
762: }
763: if { [catch { expr $test }] } { return 0 } else {
764: switch $type {
765: year {
766: if { $test < 1990 } { return $lowfail }
767: if { $test > 9999 } { return 0 }
768: if { [string length $temp] > 4 } { return 0 }
769: }
770: month {
771: if { $test < 1 } { return $lowfail }
772: if { $test > 12 } { return 0 }
773: if { [string length $temp] > 2 } { return 0 }
774: }
775: day {
776: if { $test < 1 } { return $lowfail }
777: if { $test > 31 } { return 0 }
778: if { [string length $temp] > 2 } { return 0 }
779: }
780: hour {
781: if { $test < 0 } { return 0 }
782: if { $test > 23 } { return 0 }
783: if { [string length $temp] > 2 } { return 0 }
784: }
785: minute {
786: if { $test < 0 } { return 0 }
787: if { $test > 59 } { return 0 }
788: if { [string length $temp] > 2 } { return 0 }
789: }
790: durationhour {
791: if { $test < 0 } { return 0 }
792: if { [string length $temp] > 4 } { return 0 }
793: }
794: }
795: }
796: return 1
797: }
798:
799: ###########################################################
800: # getday
801: ###########################################################
802: ###########################################################
803: ###########################################################
804: proc getday { kind } {
805: global gDates
806: if { [set day $gDates([set kind]day)] != ""} {
807: if { [set month $gDates([set kind]month)] != ""} {
808: if { [set year $gDates([set kind]year)] != ""} {
809: if { [ catch { set gDates($kind.dayoweek) \
810: [clock format [clock scan "$month/$day/$year"] \
811: -format %a] } error ] } {
812: set gDates($kind.dayoweek) ""
813: }
814: return
815: }
816: }
817: }
818: set gDates($kind.dayoweek) ""
819: }
820:
821: ###########################################################
822: # enableDateValidation
823: ###########################################################
824: ###########################################################
825: ###########################################################
826: proc enableDateValidation { toplevel } {
827: global gDates
828: set dateFrame $toplevel.dateFrame
829: foreach type { open due answer } {
830: $dateFrame.[set type]date.year configure -validate key \
831: -validatecommand "validate $type year %P"
832: $dateFrame.[set type]date.month configure -validate key \
833: -validatecommand "validate $type month %P"
834: $dateFrame.[set type]date.day configure -validate key \
835: -validatecommand "validate $type day %P"
836: $dateFrame.[set type]time.hour configure -validate key \
837: -validatecommand "validate $type hour %P"
838: $dateFrame.[set type]time.minute configure -validate key \
839: -validatecommand "validate $type minute %P"
840: }
841: $gDates(optFrame).duration.hour configure -validate key \
842: -validatecommand "validate {} durationhour %P"
843: $gDates(optFrame).duration.minute configure -validate key \
844: -validatecommand "validate duration minute %P"
845:
846: }
847:
848: ###########################################################
849: # addDateOptions
850: ###########################################################
851: ###########################################################
852: ###########################################################
853: proc addDateOptions {} {
854: global gDates
855: pack $gDates(optFrame2)
856: $gDates(optBut) configure -text "Less Options" -command "removeDateOptions"
857: }
858:
859: ###########################################################
860: # removeDateOptions
861: ###########################################################
862: ###########################################################
863: ###########################################################
864: proc removeDateOptions {} {
865: global gDates
866: pack forget $gDates(optFrame2)
867: $gDates(optBut) configure -text "More Options" -command "addDateOptions"
868: }
869:
870: ###########################################################
871: # createDateDialog
872: ###########################################################
873: ###########################################################
874: ###########################################################
875: proc createDateDialog { toplevel makedefault } {
876: global gDates gPrompt2
877:
878: catch [unset gDates]
879:
880: set infoFrame [frame $toplevel.infoFrame]
881: set sectionFrame [frame $toplevel.sectionFrame -borderwidth 4]
882: set dateFrame [frame $toplevel.dateFrame]
883: set optionsFrame [frame $toplevel.optionsFrame]
884: set buttonFrame [frame $toplevel.buttonFrame]
885: pack $infoFrame $sectionFrame $dateFrame $buttonFrame -side top
886:
887: if { $makedefault } {
888: label $sectionFrame.sectionl -text "Default value for all sections:"
889: pack $sectionFrame.sectionl
890: set gDates(sectionstart) 0
891: set gDates(sectionend) 0
892: } else {
893: grid [label $sectionFrame.sectionl -text "Dates and times are for"] \
894: -column 0 -columnspan 4 -row 0
895: grid [label $sectionFrame.section12 -text "section:"] -column 0 -row 1
896: grid [entry $sectionFrame.start -width 3 -textvariable gDates(sectionstart)] \
897: -column 1 -row 1
898: grid [label $sectionFrame.sectionl3 -text "through section: "] -column 2 -row 1
899: grid [entry $sectionFrame.end -width 3 -textvariable gDates(sectionend)] \
900: -column 3 -row 1
901: button $buttonFrame.getdefaults -text "Get Defaults" -command \
902: "setValues 0 0;enableDateValidation $toplevel"
903: pack $buttonFrame.getdefaults -side left
904: }
905:
906: grid [label $dateFrame.datel -text "Date"] -column 1 -row 0
907: grid [label $dateFrame.timel -text "Time"] -column 2 -row 0
908: grid [label $dateFrame.helpd -text "yyyy/mm/dd"] -column 1 -row 1
909: grid [label $dateFrame.helpt -text "hh:mm"] -column 2 -row 1
910: grid [label $dateFrame.openl -text "Open"] -column 0 -row 2
911: grid [set openDate [frame $dateFrame.opendate -borderwidth 2 -relief sunken]] -column 1 -row 2
912: grid [set openTime [frame $dateFrame.opentime -borderwidth 2 -relief sunken]] -column 2 -row 2
913: grid [label $dateFrame.openday -textvariable gDates(open.dayoweek)] -column 3 -row 2
914: grid [label $dateFrame.duel -text "Due"] -column 0 -row 3
915: grid [set dueDate [frame $dateFrame.duedate -borderwidth 2 -relief sunken]] -column 1 -row 3
916: grid [set dueTime [frame $dateFrame.duetime -borderwidth 2 -relief sunken]] -column 2 -row 3
917: grid [label $dateFrame.dueday -textvariable gDates(due.dayoweek)] -column 3 -row 3
918: grid [label $dateFrame.answerl -text "Answer"] -column 0 -row 4
919: grid [set answerDate [frame $dateFrame.answerdate -borderwidth 2 -relief sunken]] -column 1 -row 4
920: grid [set answerTime [frame $dateFrame.answertime -borderwidth 2 -relief sunken]] -column 2 -row 4
921: grid [label $dateFrame.ansday -textvariable gDates(answer.dayoweek)] -column 3 -row 4
922:
923:
924: foreach type { open due answer } {
925: entry [set [set type]Date].year -width 4 -textvariable gDates([set type]year)
926: label [set [set type]Date].sl1 -text "/"
927: entry [set [set type]Date].month -width 2 -textvariable gDates([set type]month)
928: label [set [set type]Date].sl2 -text "/"
929: entry [set [set type]Date].day -width 2 -textvariable gDates([set type]day)
930: entry [set [set type]Time].hour -width 2 -textvariable gDates([set type]hour)
931: label [set [set type]Time].colon -text ":"
932: entry [set [set type]Time].minute -width 2 -textvariable gDates([set type]minute)
933: pack [set [set type]Date].year [set [set type]Date].sl1 \
934: [set [set type]Date].month [set [set type]Date].sl2 \
935: [set [set type]Date].day -side left
936: pack [set [set type]Time].hour [set [set type]Time].colon \
937: [set [set type]Time].minute -side left
938: }
939:
940: set optionsFrame3 [frame $optionsFrame.options]
941: set gDates(optFrame) [ set optionsFrame2 [frame $optionsFrame3.options ] ]
942: pack $gDates(optFrame) $optionsFrame3
943: set gDates(optFrame2) $optionsFrame
944:
945: set durationFrame [frame $optionsFrame2.duration]
946: checkbutton $optionsFrame2.view -variable gDates(viewbetween) \
947: -text "Allow Viewing between Due and Answer dates"
948: checkbutton $optionsFrame2.response -variable gDates(inhibitresponse) \
949: -text "Inhibit Correct/Incorrect response \n(normally only for exams/quizzes)"
950: pack $durationFrame $optionsFrame2.view $optionsFrame2.response -side top
951: set gDates(viewbetween) 1
952: set gDates(inhibitresponse) 0
953:
954: label $durationFrame.label -text "Duration"
955: entry $durationFrame.hour -width 4 -textvariable gDates(durationhour)
956: label $durationFrame.colon -text ":"
957: entry $durationFrame.minute -width 2 -textvariable gDates(durationminute)
958: pack $durationFrame.label $durationFrame.hour $durationFrame.colon \
959: $durationFrame.minute -side left
960: set gDates(durationhour) 0
961: set gDates(durationminute) 0
962:
963: button $buttonFrame.help -text "Help" -command "showHelp dateEntry"
964: button $buttonFrame.set -text "Ok" -command "set gPrompt2(ok) 1"
965: button $buttonFrame.cancel -text "Cancel" -command "set gPrompt2(ok) 0"
966: set gDates(optBut) [ button $buttonFrame.options -text "More Options" \
967: -command "addDateOptions"]
968: pack $buttonFrame.help $buttonFrame.set $buttonFrame.cancel $buttonFrame.options \
969: -side left
970: bind $toplevel <Destroy> "set gPrompt2(ok) 0"
971: bind $toplevel <KeyPress> "getday open;getday due;getday answer"
972: bind $toplevel <Return> {tkTabToWindow [tk_focusNext %W]}
973: }
974:
975: ###########################################################
976: # addCurrentDates
977: ###########################################################
978: ###########################################################
979: ###########################################################
980: proc addCurrentDates { listbox makedefault {which -1} } {
981: global gControlDates gDates
982: foreach kind { open due answer } {
983: foreach type { year month day hour minute } {
984: #tcl interprets all strings of digits with 0 as the first number as
985: #being in octal, need to prevent this from causing an error
986: if { [string length $gDates($kind$type)] > 1 && \
987: [string index $gDates($kind$type) 0] == 0 } {
988: set gDates($kind$type) [string range $gDates($kind$type) 1 end]
989: }
990: }
991: }
992: set datestring [list $gDates(sectionstart) $gDates(sectionend) \
993: [format "%04d/%02d/%02d %02d:%02d" $gDates(openyear) \
994: $gDates(openmonth) $gDates(openday) \
995: $gDates(openhour) $gDates(openminute) ] \
996: [format "%04d/%02d/%02d %02d:%02d" $gDates(dueyear) \
997: $gDates(duemonth) $gDates(dueday) \
998: $gDates(duehour) $gDates(dueminute) ] \
999: [format "%04d/%02d/%02d %02d:%02d" $gDates(answeryear) \
1000: $gDates(answermonth) $gDates(answerday) \
1001: $gDates(answerhour) $gDates(answerminute) ] \
1002: [format "%d:%d" $gDates(durationhour) $gDates(durationminute)] \
1003: $gDates(inhibitresponse) $gDates(viewbetween) ]
1004: if { $makedefault } {
1005: if { ([info globals gControlDates] == "") || ($gControlDates == "") } {
1006: set gControlDates [list $datestring]
1007: } else {
1008: set gControlDates [lreplace $gControlDates 0 0 $datestring]
1009: }
1010: } else {
1011: if { $which > -1 } {
1012: # puts "$gControlDates=$which=$which=$datestring"
1013: set gControlDates [lreplace $gControlDates $which $which $datestring]
1014: } else {
1015: lappend gControlDates $datestring
1016: }
1017: }
1018: updateDateBox $listbox
1019: }
1020:
1021: ###########################################################
1022: # setValues
1023: ###########################################################
1024: ###########################################################
1025: ###########################################################
1026: proc setValues { which {doSections 1} } {
1027: global gControlDates gDates
1028: set datestring [lindex $gControlDates $which]
1029: if { $doSections } {
1030: set gDates(sectionstart) [lindex $datestring 0]
1031: set gDates(sectionend) [lindex $datestring 1]
1032: }
1033: foreach type {open due answer} element {2 3 4} {
1034: set gDates([set type]year) [lindex [split [lindex $datestring $element] "/" ] 0]
1035: set gDates([set type]month) [lindex [split [lindex $datestring $element] "/" ] 1]
1036: set gDates([set type]day) [lindex [split [lindex [lindex $datestring $element] 0] "/" ] 2]
1037: set gDates([set type]hour) [lindex [split [lindex [lindex $datestring $element] 1] ":" ] 0]
1038: set gDates([set type]minute) [lindex [split [lindex [lindex $datestring $element] 1] ":" ] 1]
1039: }
1040: set gDates(durationhour) [lindex [split [lindex $datestring 5] ":" ] 0]
1041: set gDates(durationminute) [lindex [split [lindex $datestring 5] ":" ] 1]
1042: set gDates(inhibitresponse) [lindex $datestring 6]
1043: set gDates(viewbetween) [lindex $datestring 7]
1044: getday open
1045: getday due
1046: getday answer
1047: }
1048:
1049: ###########################################################
1050: # changeDate
1051: ###########################################################
1052: ###########################################################
1053: ###########################################################
1054: proc changeDate { listbox } {
1055: global gDates gPrompt2 gControlDates
1056:
1057: if { ![winfo exists $listbox] } { return }
1058: if { [winfo exists .adddate] } { return }
1059: if { [set which [$listbox index anchor]] == 0 } { set makedefault 1 } else {
1060: set makedefault 0 }
1061: if { $which == [$listbox index end] } {addDate $listbox;return}
1062: set changeDate [toplevel .changeDate]
1063: createDateDialog $changeDate $makedefault
1064: setValues $which
1065: enableDateValidation $changeDate
1066:
1067: if { $makedefault } {
1068: set gDates(sectionstart) 0
1069: set gDates(sectionend) 0
1070: }
1071:
1072: Centre_Dialog $changeDate default
1073: update
1074:
1075: focus $changeDate
1076: capaRaise $changeDate
1077: capaGrab $changeDate
1078: set done 0
1079: while { $done != 1 } {
1080: vwait gPrompt2(ok)
1081: if { $gPrompt2(ok) == 1 } {
1082: if { 1 != [set done [checkDateFields]] } {
1083: displayError "Please correct field: $done"
1084: set done 0
1085: } else {
1086: if { [dueAnswerOrder] } {
1087: if { "Yes" == [makeSure "Right now answers are available before an assignment is due. Would you like to change this?."]} {
1088: set done 0
1089: } else {
1090: set done 1
1091: }
1092: }
1093: }
1094: } else {
1095: set done 1
1096: }
1097: }
1098: capaGrab release $changeDate
1099: bind $changeDate <Destroy> ""
1100: destroy $changeDate
1101: if {$gPrompt2(ok) == 1 } {
1102: addCurrentDates $listbox $makedefault $which
1103: }
1104: return
1105: }
1106:
1107: ###########################################################
1108: # addDate
1109: ###########################################################
1110: ###########################################################
1111: ###########################################################
1112: proc addDate { listbox } {
1113: global gDates gPrompt2
1114:
1115: if { ![winfo exists $listbox ] } { return }
1116: if { [winfo exists .adddate ] } { return }
1117: if { [$listbox index end] == 0 } { set makedefault 1 } else { set makedefault 0 }
1118: set addDate [toplevel .adddate]
1119:
1120: createDateDialog $addDate $makedefault
1121: enableDateValidation $addDate
1122:
1123: Centre_Dialog $addDate default
1124: update
1125:
1126: focus $addDate
1127: capaRaise $addDate
1128: capaGrab $addDate
1129: set done 0
1130: while { $done != 1 } {
1131: vwait gPrompt2(ok)
1132: if { $gPrompt2(ok) == 1 } {
1133: if { 1 != [set done [checkDateFields]] } {
1134: displayError "Please correct field: $done"
1135: set done 0
1136: } else {
1137: if { [dueAnswerOrder] } {
1138: if { "Yes" == [makeSure "Right now answers are available before an assignment is due. Would you like to change this?."]} {
1139: set done 0
1140: } else {
1141: set done 1
1142: }
1143: }
1144: }
1145: } else {
1146: set done 1
1147: }
1148: }
1149: capaGrab release $addDate
1150: bind $addDate <Destroy> ""
1151: destroy $addDate
1152: if {$gPrompt2(ok) == 1 } {
1153: addCurrentDates $listbox $makedefault
1154: }
1155: return
1156: }
1157:
1158: ###########################################################
1159: # createDBHeader
1160: ###########################################################
1161: ###########################################################
1162: ###########################################################
1163: proc createDBHeader {} {
1164: global gNumberParsedText gPrompt gLoadHeaderSet gControlDates \
1165: gSetNumberText gHeaderQCount gEnableDiscussion gFile
1166:
1167: if { $gNumberParsedText == "" } {
1168: displayError "You must first preview the file before creating the \
1169: DB header."
1170: return
1171: }
1172:
1173: if { [winfo exists .headerPrompt] } {
1174: capaRaise .headerPrompt
1175: return
1176: }
1177:
1178: set dialog [toplevel .headerPrompt -borderwidth 10]
1179: wm geo $dialog "+200+200"
1180: wm title $dialog "Creating DB Header"
1181:
1182: message $dialog.msg -text "Header Information" -aspect 1000
1183: set loadFrame [frame $dialog.loadFrame -borderwidth 4 -relief sunken]
1184: set infoFrame [frame $dialog.infoFrame -borderwidth 4 -relief sunken]
1185: set optionFrame [frame $dialog.options]
1186: set buttonFrame [frame $dialog.buttons -bd 10]
1187: pack $dialog.msg $loadFrame $infoFrame $optionFrame $buttonFrame -side top -fill x
1188:
1189: set legendFrame [frame $infoFrame.legendFrame]
1190: set listFrame [frame $infoFrame.listFrame]
1191: set commandFrame [frame $infoFrame.commandFrame]
1192: pack $legendFrame $listFrame $commandFrame -side top
1193:
1194: label $legendFrame.legend1 -text " Section# | Open | Due | Answer "
1195: label $legendFrame.legend2 -text "Start End| Date Time | Date Time | Date Time "
1196: pack $legendFrame.legend1 $legendFrame.legend2 -side top
1197:
1198: set listbox [listbox $listFrame.list -width 63 -yscrollcommand "$listFrame.scroll set" ]
1199: scrollbar $listFrame.scroll -command "$listbox yview"
1200: pack $listFrame.list $listFrame.scroll -side left
1201: updateDateBox $listbox
1202:
1203: button $commandFrame.add -text "Add" -command "addDate $listbox"
1204: button $commandFrame.change -text "Change" -command "changeDate $listbox"
1205: button $commandFrame.delete -text "Delete" -command "deleteDate $listbox"
1206: pack $commandFrame.add $commandFrame.change $commandFrame.delete -side left
1207: bind $listbox <Double-ButtonPress-1> "changeDate $listbox"
1208:
1209: message $loadFrame.msg -text "Load header information from set:" \
1210: -aspect 1000
1211: set gLoadHeaderSet $gSetNumberText
1212: entry $loadFrame.entry -textvariable gLoadHeaderSet -width 2
1213: button $loadFrame.load -text "load" -command "loadDates $listbox"
1214: pack $loadFrame.msg $loadFrame.entry $loadFrame.load -side left
1215:
1216: if { [file exists [file join [file dirname $gFile] discussion $gSetNumberText]] } {
1217: set gEnableDiscussion 1
1218: } else {
1219: set gEnableDiscussion 0
1220: }
1221: checkbutton $optionFrame.discuss -text "Enable Discussion Forum" \
1222: -variable gEnableDiscussion
1223: pack $optionFrame.discuss
1224:
1225: button $buttonFrame.ok -text Set -command { set gPrompt(ok) 1 } \
1226: -underline 0
1227: button $buttonFrame.cancel -text Cancel -command { set gPrompt(ok) 0 } \
1228: -underline 0
1229: pack $buttonFrame.ok $buttonFrame.cancel -side left
1230:
1231: bind $dialog <Destroy> "set gPrompt(ok) 0"
1232: Centre_Dialog $dialog default
1233: update
1234:
1235: focus $dialog
1236: capaRaise $dialog
1237: capaGrab $dialog
1238: bind $dialog <Destroy> ""
1239: set done 0
1240: while { $done != 1 } {
1241: vwait gPrompt(ok)
1242: if { $gPrompt(ok) == 1 } {
1243: set done [checkHeaderForDefault]
1244: if { $done == 0 } {
1245: displayError "Must have a Default setting."
1246: }
1247: } else {
1248: set done 1
1249: }
1250: }
1251: capaGrab release $dialog
1252: destroy $dialog
1253: if {$gPrompt(ok) == 1 } {
1254: updateDiscussion
1255: eval updateHeader [ eval concat $gControlDates ]
1256: }
1257:
1258: return
1259:
1260: }
1261:
1262: ###########################################################
1263: # updateDiscussion
1264: ###########################################################
1265: ###########################################################
1266: ###########################################################
1267: proc updateDiscussion {} {
1268: global gFile gSetNumberText gEnableDiscussion
1269: set dir [file dirname $gFile]
1270: set disDir [file join $dir discussion $gSetNumberText]
1271: set logDir [file join $dir discussion logs]
1272: if { $gEnableDiscussion } {
1273: if { ![file exists $disDir] } {
1274: if { [file exists $disDir.unavailable] } {
1275: exec mv $disDir.unavailable $disDir
1276: } else {
1277: file mkdir $disDir
1278: file attributes $disDir -permissions 0777
1279: }
1280: }
1281: if { ![file exists $logDir] } {
1282: file mkdir [file join $dir discussion logs]
1283: file attributes [file join $dir discussion logs] -permissions 0777
1284: }
1285: } else {
1286: if { [file exists $disDir] } { exec mv $disDir $disDir.unavailable }
1287: }
1288: }
1289:
1290: ###########################################################
1291: # allFieldsComplete2
1292: ###########################################################
1293: ###########################################################
1294: ###########################################################
1295: proc allFieldsComplete2 {} {
1296: global gLoadHeaderSet gControlDates
1297:
1298: if { [string length $gOpenDate] != 8 } {
1299: return 0
1300: } elseif { [string length $gOpenTime] != 5 } {
1301: return 0
1302: } elseif { [string length $gDueDate] != 8 } {
1303: return 0
1304: } elseif { [string length $gDueTime] != 5 } {
1305: return 0
1306: } elseif { [string length $gAnswerDate] != 8 } {
1307: return 0
1308: } elseif { [string length $gAnswerTime] != 5 } {
1309: return 0
1310: } else {
1311: return 1
1312: }
1313: }
1314:
1315: ###########################################################
1316: # createFindWindow
1317: ###########################################################
1318: ###########################################################
1319: ###########################################################
1320: proc createFindWindow { {num 0} } {
1321: global gFind gWindowMenu gFindListbox
1322:
1323: if { [winfo exists .find] } {
1324: capaRaise .find
1325: pickFindFile $num
1326: return
1327: }
1328:
1329: set find [toplevel .find]
1330: $gWindowMenu add command -label "Find" -command "capaRaise $find"
1331: wm title $find "Find"
1332:
1333: set findFrame [frame $find.findFrame -width 5i]
1334: set replaceFrame [frame $find.replaceFrame ]
1335: set optionsFrame [frame $find.optionsFrame ]
1336: set buttonFrame [frame $find.buttonsFrame ]
1337: pack $findFrame $replaceFrame $optionsFrame $buttonFrame -side top \
1338: -anchor e
1339: pack configure $buttonFrame -anchor center
1340:
1341: message $findFrame.msg -text "Find:" -aspect 10000
1342: entry $findFrame.entry -width 50 -textvariable gFind(find)
1343: pack $findFrame.msg $findFrame.entry -side left
1344:
1345: message $replaceFrame.msg -text "Replace with:" -aspect 10000
1346: entry $replaceFrame.entry -width 50 -textvariable gFind(replace)
1347: pack $replaceFrame.msg $replaceFrame.entry -side left
1348:
1349: set fileFrame [frame $optionsFrame.file]
1350: set scopeFrame [frame $optionsFrame.scope -relief groove -borderwidth 4]
1351: set findOptionsFrame [frame $optionsFrame.findOptionsFrame -relief \
1352: groove -borderwidth 4]
1353: pack $fileFrame $scopeFrame $findOptionsFrame -side left
1354:
1355: set fileList [ frame $fileFrame.list ]
1356: set fileScroll [frame $fileFrame.scroll ]
1357: pack $fileList $fileScroll -side left
1358: pack configure $fileScroll -fill y
1359:
1360: set gFindListbox [listbox $fileList.list -width 35 -height 4 \
1361: -xscrollcommand "$fileList.scroll set" \
1362: -yscrollcommand "$fileScroll.scroll set" \
1363: -exportselection no]
1364: scrollbar $fileList.scroll -orient h -command "$fileList.list xview"
1365: pack $fileList.list $fileList.scroll -side top
1366: pack configure $fileList.scroll -fill x
1367: pack configure $fileList.list -fill both -expand 1
1368: $fileList.list xview moveto 1
1369:
1370: scrollbar $fileScroll.scroll -orient v \
1371: -command "$fileList.list yview"
1372: pack $fileScroll.scroll -fill y -expand 1
1373:
1374: message $scopeFrame.msg -text "Replace All Scope" -aspect 10000
1375: radiobutton $scopeFrame.file -value "File" -variable gFind(scope) -text \
1376: "Entire File" \
1377:
1378: radiobutton $scopeFrame.selection -value "Selection" -variable \
1379: gFind(scope) -text "Selection"
1380: pack $scopeFrame.msg $scopeFrame.file $scopeFrame.selection
1381: pack configure $scopeFrame.file $scopeFrame.selection -anchor w
1382: set gFind(scope) File
1383:
1384: message $findOptionsFrame.msg -text "Find Options" -aspect 10000
1385: radiobutton $findOptionsFrame.ignoreCase -variable gFind(findOption) \
1386: -text "Ignore Case" -value "-nocase"
1387: radiobutton $findOptionsFrame.exactCase -variable gFind(findOption) \
1388: -text "Exact Case" -value "-exact"
1389: radiobutton $findOptionsFrame.regexp -variable gFind(findOption) \
1390: -text "Regular Expression" -value "-regexp"
1391: pack $findOptionsFrame.msg $findOptionsFrame.ignoreCase \
1392: $findOptionsFrame.exactCase $findOptionsFrame.regexp
1393: pack $findOptionsFrame.ignoreCase $findOptionsFrame.exactCase \
1394: $findOptionsFrame.regexp -anchor w
1395: set gFind(findOption) "-nocase"
1396:
1397: button $buttonFrame.replaceAll -text "Replace All" -command "replaceAll"
1398: button $buttonFrame.replace -text "Replace" -command "replace"
1399: button $buttonFrame.replaceFind -text "Replace and Find" -command \
1400: "replaceFind"
1401: button $buttonFrame.previous -text "Previous" -command "previous"
1402: button $buttonFrame.next -text "Next <Return>" -command "next"
1403: bind $find <KeyPress-Return> next
1404: button $buttonFrame.close -text "Close" -command "removeWindowEntry Find
1405: destroy $find"
1406: bind $find <Destroy> "removeWindowEntry Find"
1407: pack $buttonFrame.replaceAll $buttonFrame.replace \
1408: $buttonFrame.replaceFind $buttonFrame.previous \
1409: $buttonFrame.next $buttonFrame.close -side left
1410:
1411: Centre_Dialog $find default
1412: updateFindList
1413: pickFindFile $num
1414: }
1415:
1416: ###########################################################
1417: # pickFindFile
1418: ###########################################################
1419: ###########################################################
1420: ###########################################################
1421: proc pickFindFile { num } {
1422: global gFindListbox gFindList gRefFile gFile
1423: if { [catch {set gFindListbox}] } { return }
1424: if { ![winfo exists $gFindListbox] } { return }
1425: if { $num == 0 } {
1426: set newfile $gFile
1427: } else {
1428: set newfile $gRefFile($num)
1429: }
1430: for {set i 0} {$i<[llength $gFindList(files)]} {incr i} {
1431: set file [lindex $gFindList(files) $i]
1432: if { $file == $newfile } { break }
1433: }
1434: if { $i < [llength $gFindList(files)] } {
1435: $gFindListbox selection clear 0 end
1436: $gFindListbox selection set $i
1437: }
1438: }
1439:
1440: ###########################################################
1441: # updateFindList
1442: ###########################################################
1443: ###########################################################
1444: ###########################################################
1445: proc updateFindList {} {
1446: global gFindListbox gFindList
1447: if { [catch {set gFindListbox}] } { return }
1448: if { ![winfo exists $gFindListbox] } { return }
1449: $gFindListbox delete 0 end
1450: eval "$gFindListbox insert end $gFindList(files)"
1451: $gFindListbox xview moveto 1
1452: }
1453:
1454: ###########################################################
1455: # whichFile
1456: ###########################################################
1457: ###########################################################
1458: ###########################################################
1459: proc whichFile { refNum } {
1460: global gRefFile gFile
1461: if { $refNum > 0 } {
1462: return $gRefFile($refNum)
1463: } else {
1464: if { $refNum < 0 } {
1465: switch -- $refNum {
1466: -1 { return "Preview Window" }
1467: -2 { return "Parse Errors Window" }
1468: -3 { return "LaTeX Output Window" }
1469: }
1470: } else {
1471: return $gFile
1472: }
1473: }
1474: }
1475: ###########################################################
1476: # addFindList
1477: ###########################################################
1478: ###########################################################
1479: ###########################################################
1480: proc addFindList { {refNum 0} } {
1481: global gFindList gRefFile gFile
1482:
1483: set file [whichFile $refNum]
1484: lappend gFindList(files) $file
1485: lappend gFindList(refNum) $refNum
1486: updateFindList
1487: }
1488:
1489: ###########################################################
1490: # removeFindList
1491: ###########################################################
1492: ###########################################################
1493: ###########################################################
1494: proc removeFindList { {refNum 0} } {
1495: global gFindList gRefFile gFile
1496:
1497: set file [whichFile $refNum]
1498: set k [llength $gFindList(refNum)]
1499: for {set i 0} {$i < $k } { incr i } {
1500: if { $refNum == [lindex $gFindList(refNum) $i] } { break }
1501: }
1502: if { $i != $k } {
1503: set gFindList(refNum) [lreplace $gFindList(refNum) $i $i]
1504: set gFindList(files) [lreplace $gFindList(files) $i $i]
1505: }
1506: updateFindList
1507: }
1508:
1509: ###########################################################
1510: # getFindWindow
1511: ###########################################################
1512: ###########################################################
1513: ###########################################################
1514: proc getFindWindow { {refNumVar none} } {
1515: global gFindListbox gFindList gRefText gTextWindow \
1516: gPreviewText gParseErrorsText gCreateDviText
1517:
1518: set current [$gFindListbox curselection]
1519: if { $current == "" } { set current 0 }
1520: if { [set refNum [lindex $gFindList(refNum) $current] ] } {
1521: if { $refNum < 0 } {
1522: switch -- $refNum {
1523: -1 { set window $gPreviewText }
1524: -2 { set window $gParseErrorsText }
1525: -3 { set window $gCreateDviText }
1526: }
1527: } else {
1528: set window $gRefText($refNum)
1529: }
1530: } else {
1531: set window $gTextWindow
1532: }
1533: if { $refNumVar != "none" } {
1534: upvar $refNumVar refNumUp
1535: set refNumUp $refNum
1536: }
1537: return $window
1538: }
1539:
1540: ###########################################################
1541: # replaceAll
1542: ###########################################################
1543: ###########################################################
1544: ###########################################################
1545: proc replaceAll {} {
1546: global gFind gCreateImportLinks
1547:
1548: set window [getFindWindow]
1549: if { ![winfo exists $window] } { return }
1550:
1551: set gCreateImportLinks 0
1552: set num 0
1553: switch $gFind(scope) {
1554: File
1555: {
1556: $window mark set insert 0.0
1557: set begin 0.0
1558: while { [nextRegion $begin end] != "" } {
1559: incr num
1560: replace
1561: if { ! ($num%10) } { update idletasks }
1562: set begin sel.last
1563: }
1564: }
1565: Selection
1566: {
1567: set error [ catch {$window mark set replace sel.first}]
1568: if { $error != 0 } { return }
1569: $window mark set capaBegin sel.first
1570: $window mark set capaEnd sel.last
1571: while { [set begin [nextRegion capaBegin capaEnd]] != "" } {
1572: incr num
1573: replace
1574: $window mark set capaBegin $begin
1575: }
1576: }
1577: }
1578: if { $num == 1 } { set s {} } { set s s }
1579: update idletasks
1580: set gCreateImportLinks 1
1581: getFindWindow refNum
1582: if { $refNum >= 0 } { registerCreateImportLinks $refNum 0.0 end }
1583: displayMessage "Replaced $num occurance$s"
1584: }
1585:
1586: ###########################################################
1587: ###########################################################
1588: ###########################################################
1589: ###########################################################
1590: proc replace {} {
1591: global gFind
1592:
1593: set refNum 0
1594: set window [getFindWindow refNum]
1595: if { ![winfo exist $window] } { return }
1596:
1597: set error [ catch {$window mark set replace sel.first}]
1598: if { $error == 0 } {
1599: $window delete sel.first sel.last
1600: } else {
1601: $window mark set replace insert
1602: }
1603:
1604: $window insert replace "$gFind(replace)"
1605:
1606: catch {$window tag remove sel sel.first sel.last}
1607:
1608: $window tag add sel "replace - [string length "$gFind(replace)"] \
1609: chars " replace
1610: $window see replace
1611:
1612: $window mark unset replace
1613: }
1614:
1615: ###########################################################
1616: ###########################################################
1617: ###########################################################
1618: ###########################################################
1619: proc replaceFind {} {
1620: set window [getFindWindow]
1621: if { ![winfo exists $window] } { return }
1622: replace
1623: next
1624: }
1625:
1626: ###########################################################
1627: ###########################################################
1628: ###########################################################
1629: ###########################################################
1630: proc searchBody { found } {
1631: global gFind
1632:
1633: set window [getFindWindow refNum]
1634: if { ![winfo exists $window] } { return }
1635:
1636: catch {$window tag remove sel sel.first sel.last}
1637: $window tag add sel $found "$found + [string length $gFind(find)] \
1638: chars"
1639: $window see $found
1640: $window mark set insert "$found + [string length $gFind(find)] chars"
1641: }
1642:
1643: ###########################################################
1644: ###########################################################
1645: ###########################################################
1646: ###########################################################
1647: proc previous {} {
1648: global gFind
1649:
1650: set window [getFindWindow]
1651: if { ![winfo exists $window] } { return }
1652:
1653: if { [catch { set found [$window search $gFind(findOption) -backwards -- \
1654: $gFind(find) "sel.first - 1 c" ] } ] } {
1655: set found [ $window search $gFind(findOption) -backwards -- \
1656: $gFind(find) "insert - 1 c" ]
1657: }
1658: if { $found != "" } { searchBody $found }
1659: return $found
1660: }
1661:
1662: ###########################################################
1663: ###########################################################
1664: ###########################################################
1665: ###########################################################
1666: proc next {} {
1667: global gFind
1668:
1669: set window [getFindWindow]
1670: if { ![winfo exists $window] } { return }
1671:
1672: set found [ $window search $gFind(findOption) -forwards -- \
1673: $gFind(find) "insert + 1 c" ]
1674: if { $found != "" } {
1675: searchBody $found
1676: } else {
1677: displayMessage "Search String Not Found"
1678: }
1679: return $found
1680: }
1681:
1682: ###########################################################
1683: ###########################################################
1684: ###########################################################
1685: ###########################################################
1686: proc nextRegion { begin end } {
1687: global gFind
1688:
1689: set window [getFindWindow]
1690: if { ![winfo exists $window] } { return }
1691:
1692: set error [ catch {set found [ $window search $gFind(findOption) \
1693: -forwards -- $gFind(find) $begin $end ] } ]
1694: if { $error != 0 } { set found "" }
1695: if { $found != "" } {
1696: searchBody $found
1697: set found "$found + [string length $gFind(find)] chars"
1698: }
1699: return $found
1700: }
1701:
1702: ###########################################################
1703: ###########################################################
1704: ###########################################################
1705: ###########################################################
1706: proc createLineWindow {} {
1707: global gLineNumber gCharacterNumber gLineNumberGoto gCharacterNumberGoto
1708: global gWindowMenu
1709:
1710: if { [winfo exists .lineWindow] } {
1711: capaRaise .lineWindow
1712: return
1713: }
1714:
1715: set lineWindow [toplevel .lineWindow]
1716: $gWindowMenu add command -label "LineSelect" -command \
1717: "capaRaise $lineWindow"
1718: wm title $lineWindow "Select Line"
1719:
1720: label $lineWindow.line -text "Line:"
1721: grid $lineWindow.line -column 1 -row 0
1722: label $lineWindow.character -text "Character:"
1723: grid $lineWindow.character -column 2 -row 0
1724: label $lineWindow.current -text "Current:"
1725: grid $lineWindow.current -column 0 -row 1
1726: label $lineWindow.lineNumber -textvariable gLineNumber
1727: grid $lineWindow.lineNumber -column 1 -row 1
1728: label $lineWindow.characterNumber -textvariable gCharacterNumber
1729: grid $lineWindow.characterNumber -column 2 -row 1
1730: label $lineWindow.goto -text "Goto:"
1731: grid $lineWindow.goto -column 0 -row 2
1732: entry $lineWindow.lineEntry -textvariable gLineNumberGoto
1733: grid $lineWindow.lineEntry -column 1 -row 2
1734: set gLineNumberGoto ""
1735: entry $lineWindow.characterEntry -textvariable gCharacterNumberGoto
1736: grid $lineWindow.characterEntry -column 2 -row 2
1737: set gCharacterNumberGoto ""
1738: button $lineWindow.close -text "Close" -command "destroy $lineWindow
1739: removeWindowEntry LineSelect"
1740: bind $lineWindow <Destroy> "removeWindowEntry LineSelect"
1741: grid $lineWindow.close -column 1 -row 3
1742: button $lineWindow.gotoButton -text "Goto<Return>" -command "gotoLine"
1743: grid $lineWindow.gotoButton -column 2 -row 3
1744:
1745: bind $lineWindow <KeyPress-Return> gotoLine
1746:
1747: Centre_Dialog $lineWindow default
1748: }
1749:
1750: ###########################################################
1751: ###########################################################
1752: ###########################################################
1753: ###########################################################
1754: proc gotoLine {} {
1755: global gTextWindow gLineNumberGoto gCharacterNumberGoto
1756: if { [catch {set gTextWindow}] } { return }
1757: if { ![winfo exists $gTextWindow] } { return }
1758:
1759: if { $gCharacterNumberGoto == "" } {
1760: if { $gLineNumberGoto == "" } {
1761: return
1762: } else {
1763: $gTextWindow mark set insert $gLineNumberGoto.0
1764: catch {$gTextWindow tag remove sel sel.first sel.last}
1765: $gTextWindow tag add sel "insert linestart" "insert lineend"
1766: $gTextWindow see insert
1767: }
1768: } else {
1769: if { $gLineNumberGoto == "" } {
1770: $gTextWindow mark set insert "insert linestart + \
1771: $gCharacterNumberGoto chars"
1772: catch {$gTextWindow tag remove sel sel.first sel.last}
1773: $gTextWindow tag add sel "insert - 1 chars " insert
1774: $gTextWindow see insert
1775: } else {
1776: $gTextWindow mark set insert $gLineNumberGoto.$gCharacterNumberGoto
1777: catch {$gTextWindow tag remove sel sel.first sel.last}
1778: $gTextWindow tag add sel "$gLineNumberGoto.$gCharacterNumberGoto \
1779: - 1 chars " "$gLineNumberGoto.$gCharacterNumberGoto"
1780: $gTextWindow see insert
1781: }
1782: }
1783: }
1784:
1785: proc faster {} {
1786: global gFasterParsing
1787: puts $gFasterParsing
1788: }
1789:
1790: ###########################################################
1791: # createPrefsWindow
1792: ###########################################################
1793: ###########################################################
1794: ###########################################################
1795: proc createPrefsWindow {} {
1796: global gPrefs gWindowMenu gEditWindow gFile gWhichFile gPrefsEditWindow \
1797: gFasterParsing
1798: if { [catch {set gEditWindow}] } { return }
1799: if { ![winfo exists $gEditWindow] } { return }
1800: if { [winfo exists .prefs] } { capaRaise .prefs; return }
1801:
1802: set prefs [toplevel .prefs]
1803: $gWindowMenu add command -label "Prefrences" -command "capaRaise $prefs"
1804: wm title $prefs "Preferences"
1805:
1806: set frameAll [frame $prefs.frameAll -relief groove -borderwidth 4]
1807: pack $frameAll -expand true -fill both
1808:
1809: set frameFile [frame $frameAll.file]
1810: set frameInfo [frame $frameAll.info -relief groove -borderwidth 4 ]
1811: set frameButton [frame $frameAll.button ]
1812: pack $frameButton $frameInfo $frameFile -side top -expand false
1813: pack configure $frameButton -expand false -anchor center
1814:
1815: message $frameInfo.msg -text "Print Out"
1816: radiobutton $frameInfo.problem -text "Problems Only" -value "Problem" \
1817: -variable gPrefs(info)
1818: radiobutton $frameInfo.problemandanswer -text "Problems and Answers" \
1819: -value "ProblemAnswer" -variable gPrefs(info)
1820: radiobutton $frameInfo.answer -text "Answers Only" -value "Answer" \
1821: -variable gPrefs(info)
1822: pack $frameInfo.msg $frameInfo.problem $frameInfo.problemandanswer \
1823: $frameInfo.answer -side left -expand false -anchor w
1824:
1825:
1826: set selectMenu [tk_optionMenu $frameFile.menu gWhichFile HTMLheader HTMLfooter \
1827: TeXheader TeXfooter]
1828: set frameEdit [frame $frameFile.edit]
1829: pack $frameFile.menu $frameEdit
1830: pack configure $frameEdit -expand true -fill both
1831: trace variable gWhichFile w changePrefFile
1832:
1833: scrollbar $frameEdit.scroll -orient vertical -command "$frameEdit.text yview"
1834: set gPrefsEditWindow [text $frameEdit.text -yscrollcommand \
1835: "$frameEdit.scroll set" -wrap char -height 20 -width 80]
1836: pack $frameEdit.scroll $frameEdit.text -side left
1837: pack configure $frameEdit.scroll -expand false -fill y
1838: pack configure $frameEdit.text -expand true -fill both
1839:
1840: checkbutton $frameButton.faster -text "Faster Parsing" -command faster \
1841: -variable gFasterParsing
1842: button $frameButton.impcolor -text "/IMP color" -command "getColor IMP_color"
1843: button $frameButton.commentcolor -text "// color" -command "getColor comment_color"
1844: button $frameButton.config -text "Reread capa.config" -command "rereadCapaConfig"
1845: button $frameButton.ok -text "Dismiss" -command "destroy $prefs
1846: trace vdelete gWhichFile w changePrefFile
1847: removeWindowEntry Prefrences"
1848: bind $prefs <Destroy> "removeWindowEntry Preferences"
1849: button $frameButton.save -text "Save All" -command "savePrefs"
1850: pack $frameButton.impcolor $frameButton.commentcolor $frameButton.config \
1851: $frameButton.ok $frameButton.save $frameButton.faster -side left
1852:
1853: foreach file {HTMLheader HTMLfooter TeXheader TeXfooter} {
1854: if { [ catch {
1855: set filename [file join [file dirname $gFile] $file ]
1856: set fileId [open $filename r]
1857: set gPrefs($file) [read $fileId [file size $filename ]]
1858: close $fileId } errors ] } {
1859: set gPrefs($file) ""
1860: }
1861: }
1862: set gPrefs(currentFile) ""
1863: set gWhichFile HTMLheader
1864:
1865:
1866: Centre_Dialog $prefs default
1867: }
1868:
1869: ###########################################################
1870: # getColor
1871: ###########################################################
1872: ###########################################################
1873: ###########################################################
1874: proc getColor { whatfor } {
1875: global gCapaConfig gUniqueNumber gRefText
1876: set color [tk_chooseColor -initialcolor $gCapaConfig($whatfor)]
1877: set gCapaConfig($whatfor) $color
1878: if { $color != "" } { updateColors }
1879: displayMessage "To keep this color, put \"$whatfor = $color\" in the capa.config file."
1880: }
1881:
1882: ###########################################################
1883: # updateColors
1884: ###########################################################
1885: ###########################################################
1886: ###########################################################
1887: proc updateColors {} {
1888: global gCapaConfig gUniqueNumber gRefText
1889: set todo [array names gRefText]
1890: lappend todo 0
1891: displayStatus "Updating Colors . . ." both
1892: set num 0
1893: foreach win $todo {
1894: createImportLinks $win 0.0 end
1895: incr num
1896: updateStatusBar [expr $num/double([llength $todo])]
1897: }
1898: removeStatus
1899: }
1900:
1901: ###########################################################
1902: # changePrefFile
1903: ###########################################################
1904: ###########################################################
1905: ###########################################################
1906: proc changePrefFile { var1 var2 op } {
1907: global gPrefs gPrefsEditWindow gFile gWhichFile
1908:
1909: if { $gPrefs(currentFile) != "" } {
1910: set gPrefs($gPrefs(currentFile)) [$gPrefsEditWindow get 0.0 end-1c]
1911: }
1912: set gPrefs(currentFile) $gWhichFile
1913: $gPrefsEditWindow delete 0.0 end
1914: $gPrefsEditWindow insert 0.0 $gPrefs($gWhichFile)
1915: }
1916:
1917: ###########################################################
1918: # updatePrefsWindow
1919: ###########################################################
1920: ###########################################################
1921: ###########################################################
1922: proc updatePrefsWindow {} {
1923: global gPrefs gPrefsEditWindow gFile gWhichFile
1924: if { [catch {set gPrefsEditWindow}] } { return }
1925: if { ![winfo exists $gPrefsEditWindow] } { return }
1926:
1927: foreach file {HTMLheader HTMLfooter TeXheader TeXfooter} {
1928: if { [ catch {
1929: set filename [file join [file dirname $gFile] $file ]
1930: set fileId [open $filename r]
1931: set gPrefs($file) [read $fileId [file size $filename]]
1932: close $fileId } ] } {
1933: set gPrefs($file) ""
1934: }
1935: }
1936: $gPrefsEditWindow delete 0.0 end
1937: $gPrefsEditWindow insert 0.0 $gPrefs($gWhichFile)
1938: }
1939:
1940: ###########################################################
1941: ###########################################################
1942: ###########################################################
1943: ###########################################################
1944: proc savePrefs {} {
1945: global gPrefsEditWindow gFile gPrefs
1946: if { [catch {set gPrefsEditWindow}] } { return }
1947: if { ![winfo exists $gPrefsEditWindow] } { return }
1948: if { $gPrefs(currentFile) != "" } {
1949: set gPrefs($gPrefs(currentFile)) [$gPrefsEditWindow get 0.0 end-1c]
1950: }
1951: foreach file {HTMLheader HTMLfooter TeXheader TeXfooter} {
1952: if { $gPrefs($file) != "" } {
1953: set fileId [open [file join [file dirname $gFile] $file ] w]
1954: puts -nonewline $fileId $gPrefs($file)
1955: close $fileId
1956: } else {
1957: exec rm -f [file join [file dirname $gFile] $file ]
1958: }
1959: }
1960: }
1961:
1962: ###########################################################
1963: # checkHeader
1964: ###########################################################
1965: ###########################################################
1966: ###########################################################
1967: proc checkHeader { numberParsed } {
1968: global gWeightsDiffer gPartialDiffer gSetNumberText gHeaderQCount \
1969: gControlDates gLoadHeaderSet gFirstTime
1970:
1971: # if { $gFirstTime } { set gFirstTime 0; return }
1972: set gLoadHeaderSet $gSetNumberText
1973: set error [catch {getHeaderInfo}]
1974: if { $error == 1 } {
1975: set gHeaderQCount "0"
1976: set gControlDates ""
1977: displayError "The db file for this set does not yet exist."
1978: } else {
1979: set errortext ""
1980: if { ( $numberParsed != $gHeaderQCount ) } {
1981: set error 1
1982: append errortext "Number of questions ($numberParsed) is different from the number in setX.db ($gHeaderQCount). "
1983: }
1984: if { $gWeightsDiffer } {
1985: set error 1
1986: append errortext "The problem weights specified in the QZ file are different from the ones in the DB file. "
1987: }
1988: if { $gPartialDiffer } {
1989: set error 1
1990: append errortext "Whether or not a problem is hand graded as specified in the QZ file is different from the DB file. "
1991: }
1992: if { $error } {
1993: displayError "The curent DB Header does not match what the set file says it should be: $errortext. Set the DB Header!" red
1994: }
1995: }
1996: return $error
1997: }
1998:
1999: ###########################################################
2000: # fillInStudentName
2001: ###########################################################
2002: ###########################################################
2003: ###########################################################
2004: #proc notherefillInStudentName { v } {
2005: # global $v
2006:
2007: # set student [capaGetStudent [set ${v}(studentNumber)]]
2008: # set ${v}(studentName) [lindex $student [expr [llength $student] - 1] ]
2009: #}
2010:
2011: ###########################################################
2012: # studentSelectWindow
2013: ###########################################################
2014: ###########################################################
2015: ###########################################################
2016: proc studentSelectWindow { followupCommand } {
2017: global gStudentSelection gChanged gWindowMenu gEditWindow
2018: if { [catch {set gEditWindow}] } { return }
2019: if { ![winfo exists $gEditWindow] } { return }
2020: if { $gChanged } { if { [askToSave 0 0] == "Cancel" } { return } }
2021:
2022: if { [winfo exists .studentSelect] } {
2023: capaRaise .studentSelect
2024: return
2025: }
2026: set student [toplevel .studentSelect]
2027: $gWindowMenu add command -label "SelectStudent" \
2028: -command "capaRaise $student"
2029: wm title $student "Select Student"
2030:
2031: message $student.msg -text "Please specify a student to preview" \
2032: -aspect 10000
2033: set infoFrame [frame $student.frame -relief groove -borderwidth 4]
2034: set buttonFrame [frame $student.buttonFrame ]
2035: pack $student.msg $infoFrame $buttonFrame -side top
2036:
2037: button $buttonFrame.ok -text "Preview" -command \
2038: "selectStudentPreview $student $followupCommand"
2039: button $buttonFrame.cancel -text "Cancel" -command \
2040: "destroy $student
2041: trace vdelete gStudentSelection(studentNumber) w \"global gStudentSelection; set gStudentSelection(type) Specific ;#\"
2042: trace vdelete gStudentSelection(studentName) w \"global gStudentSelection; set gStudentSelection(type) Specific ;#\"
2043: removeWindowEntry SelectStudent"
2044: bind $student <Destroy> \
2045: "trace vdelete gStudentSelection(studentNumber) w \"global gStudentSelection; set gStudentSelection(type) Specific ;#\"
2046: trace vdelete gStudentSelection(studentName) w \"global gStudentSelection; set gStudentSelection(type) Specific ;#\"
2047: removeWindowEntry SelectStudent"
2048: pack $buttonFrame.ok $buttonFrame.cancel -side left
2049:
2050: set randomAnyFrame [frame $infoFrame.randomany]
2051: set randomFrame [frame $infoFrame.random]
2052: set specificFrame [frame $infoFrame.specific]
2053: set sectionFrame [frame $infoFrame.section]
2054: # pack $randomAnyFrame $randomFrame $specificFrame $sectionFrame -side top
2055: pack $randomFrame $specificFrame -side top
2056: pack configure $specificFrame -expand true -fill both
2057:
2058: radiobutton $randomAnyFrame.random -text "Randomly select a student" \
2059: -value "RandomAny" -variable gStudentSelection(type)
2060: pack $randomAnyFrame.random
2061:
2062: radiobutton $randomFrame.random -text "Randomly select one student \
2063: from section:" -value "Random" -variable gStudentSelection(type)
2064: entry $randomFrame.entry -textvariable gStudentSelection(random) -width 3
2065: pack $randomFrame.random $randomFrame.entry -side left
2066:
2067: radiobutton $specificFrame.specific -text "Specify the student by:" \
2068: -value "Specific" -variable gStudentSelection(type)
2069: set studentNumber [frame $specificFrame.studentNumber]
2070: set fullName [frame $specificFrame.fullName]
2071: pack $specificFrame.specific $studentNumber $fullName -side top
2072: pack configure $specificFrame.specific -anchor w
2073: pack configure $studentNumber $fullName -anchor e
2074:
2075: radiobutton $sectionFrame.section
2076: message $studentNumber.msg -text "Student Number: " -aspect 10000
2077: entry $studentNumber.entry -textvariable gStudentSelection(studentNumber) \
2078: -width 9 -validate key -validatecommand "limitEntry %W 9 any %P"
2079: pack $studentNumber.msg $studentNumber.entry -side left
2080:
2081: message $fullName.msg -text "Student Name: " -aspect 10000
2082: entry $fullName.msg2 -textvariable gStudentSelection(studentName) -width 35 \
2083: -validate key -validatecommand "limitEntry %W 35 any %P"
2084: pack $fullName.msg $fullName.msg2 -side left
2085:
2086: trace variable gStudentSelection(studentNumber) w \
2087: "global gStudentSelection; set gStudentSelection(type) Specific ;#"
2088: trace variable gStudentSelection(studentName) w \
2089: "global gStudentSelection; set gStudentSelection(type) Specific ;#"
2090:
2091: bind $studentNumber.entry <KeyPress-Return> \
2092: "fillInStudent gStudentSelection(studentName) gStudentSelection(studentNumber) 0"
2093: bind $fullName.msg2 <KeyPress-Return> \
2094: "fillInStudent gStudentSelection(studentName) gStudentSelection(studentNumber) 1"
2095: # $specificFrame.specific configure -command \
2096: "$studentNumber.entry configure -state normal"
2097: # $randomFrame.random configure -command \
2098: "$studentNumber.entry configure -state disabled"
2099:
2100: Centre_Dialog $student default
2101: }
2102:
2103: ###########################################################
2104: # selectStudentPreview
2105: ###########################################################
2106: ###########################################################
2107: ###########################################################
2108: proc selectStudentPreview { student followupCommand} {
2109: global gStudentSelection
2110: destroy $student
2111: if { $gStudentSelection(type) == "Specific" } {
2112: if {$gStudentSelection(studentNumber) == ""} {
2113: fillInStudent gStudentSelection(studentName) \
2114: gStudentSelection(studentNumber) 1
2115: } else {
2116: fillInStudent gStudentSelection(studentName) \
2117: gStudentSelection(studentNumber) 0
2118: }
2119: if {$gStudentSelection(studentNumber) == ""} { return }
2120: }
2121: removeWindowEntry SelectStudent
2122: $followupCommand
2123: }
2124:
2125: ###########################################################
2126: # createPreviewWindow
2127: ###########################################################
2128: ###########################################################
2129: ###########################################################
2130: proc createPreviewWindow {} {
2131: global gPreviewMode gPreviewText gPrefs gSetNumberText gStudentSelection
2132: global gWindowMenu gNumberParsedText gNumber
2133: global gLoadHeaderSet gHeaderQCount gControlDates
2134:
2135: if { ![winfo exists .preview] } {
2136:
2137: set previewWindow [toplevel .preview]
2138: $gWindowMenu add command -label "Preview" -command \
2139: "capaRaise $previewWindow"
2140: wm title $previewWindow "Preview"
2141: addFindList -1
2142:
2143: set windowFrame [frame $previewWindow.windowFrame]
2144: set buttonFrame [frame $previewWindow.buttonFrame]
2145:
2146: pack $windowFrame $buttonFrame -side bottom
2147: pack configure $windowFrame -expand true -fill both
2148: pack configure $buttonFrame -anchor e
2149:
2150: scrollbar $windowFrame.scroll -orient vertical -command \
2151: "$windowFrame.text yview"
2152: set gPreviewText [text $windowFrame.text -yscrollcommand \
2153: "$windowFrame.scroll set" -wrap char -height 40]
2154:
2155: pack $windowFrame.scroll $gPreviewText -side left -expand 0
2156: pack configure $windowFrame.scroll -expand 0 -fill y
2157: pack configure $gPreviewText -expand true -fill both
2158:
2159: button $buttonFrame.ok -text Dismiss -command "destroy $previewWindow
2160: removeWindowEntry Preview
2161: removeFindList -1"
2162: bind $previewWindow <Destroy> "removeWindowEntry Preview
2163: removeFindList -1"
2164: button $buttonFrame.save -text "Save Output" -command "saveText $gPreviewText"
2165: button $buttonFrame.stop -text "Stop Parser" -command "stopParser"
2166: button $buttonFrame.print -text "Print Output" -command "printText $gPreviewText"
2167: pack $buttonFrame.print $buttonFrame.save $buttonFrame.stop \
2168: $buttonFrame.ok -side left
2169:
2170: Centre_Dialog $previewWindow default
2171: wm withdraw $previewWindow
2172: update idletasks
2173: set win_width [winfo reqwidth $previewWindow]
2174: set win_height [winfo reqheight $previewWindow]
2175: wm geometry $previewWindow +[expr [winfo rootx $previewWindow] - \
2176: 100]+[winfo rooty $previewWindow]
2177: wm deiconify $previewWindow
2178: update
2179: } else {
2180: set previewWindow .preview
2181: $gPreviewText delete 0.0 end
2182: update
2183: }
2184:
2185: switch $gPrefs(info) {
2186: Problem { set type 0 }
2187: ProblemAnswer { set type 1 }
2188: Answer { set type 2 }
2189: }
2190: grab .preview
2191: if { [catch {
2192: switch $gPreviewMode {
2193: Enscript
2194: {
2195: set numberParsed [enscriptParse $type $gSetNumberText \
2196: $gStudentSelection(type) $gStudentSelection(random) \
2197: $gStudentSelection(studentNumber) \
2198: $gStudentSelection(studentName) gPreviewText]
2199: }
2200: TeX
2201: {
2202: set numberParsed [texParse $type $gSetNumberText \
2203: $gStudentSelection(type) $gStudentSelection(random) \
2204: $gStudentSelection(studentNumber) \
2205: $gStudentSelection(studentName) gPreviewText]
2206: }
2207: Web
2208: {
2209: set numberParsed [webParse $type $gSetNumberText \
2210: $gStudentSelection(type) $gStudentSelection(random) \
2211: $gStudentSelection(studentNumber) \
2212: $gStudentSelection(studentName) gPreviewText]
2213: }
2214: } }]} { return }
2215: grab release .preview
2216: if { $numberParsed == -1 } {
2217: destroy $previewWindow
2218: removeWindowEntry Preview
2219: return
2220: }
2221: checkHeader $numberParsed
2222: $gPreviewText tag configure problem
2223: $gPreviewText tag configure answer
2224: capaRaise $previewWindow
2225:
2226: set gNumberParsedText $numberParsed
2227: showParseErrors
2228: }
2229:
2230: ###########################################################
2231: # openError
2232: ###########################################################
2233: ###########################################################
2234: ###########################################################
2235: proc openError { file line type} {
2236: global gRefLine gLineNumberGoto gTextWindow
2237: if { $type == 2 } {
2238: set gLineNumberGoto $line
2239: gotoLine
2240: capaRaise [winfo toplevel $gTextWindow]
2241: } else {
2242: if {[set num [openReferenceFile $file]]} {
2243: update idletasks
2244: set gRefLine($num) $line
2245: gotoRefLine $num
2246: }
2247: }
2248: }
2249:
2250: ###########################################################
2251: # showParseErrors
2252: ###########################################################
2253: ###########################################################
2254: ###########################################################
2255: proc showParseErrors {} {
2256: global gParseErrorsText gWindowMenu gUniqueNumber gCapaConfig
2257:
2258: set parseErrors [getParseErrors]
2259:
2260: if { $parseErrors != "" } {
2261:
2262: if { ![winfo exists .parseErrors] } {
2263:
2264: set parseErrorsWindow [toplevel .parseErrors]
2265: $gWindowMenu add command -label "ParseErrors" -command "capaRaise \
2266: $parseErrorsWindow"
2267: wm title $parseErrorsWindow "Parse Errors"
2268: addFindList -2
2269:
2270: set windowFrame [frame $parseErrorsWindow.windowFrame]
2271: set buttonFrame [frame $parseErrorsWindow.buttonFrame]
2272:
2273: pack $windowFrame $buttonFrame -side bottom
2274: pack configure $windowFrame -expand true -fill both
2275: pack configure $buttonFrame -anchor e
2276:
2277: scrollbar $windowFrame.scroll -orient vertical -command \
2278: "$windowFrame.text yview"
2279: set gParseErrorsText [text $windowFrame.text -yscrollcommand \
2280: "$windowFrame.scroll set" -wrap char -height 40]
2281:
2282: pack $windowFrame.scroll $gParseErrorsText -side left -expand 0
2283: pack configure $windowFrame.scroll -expand 0 -fill y
2284: pack configure $gParseErrorsText -expand true -fill both
2285:
2286: button $buttonFrame.ok -text Dismiss -command \
2287: "destroy $parseErrorsWindow
2288: removeWindowEntry ParseErrors
2289: removeFindList -2"
2290: bind $parseErrorsWindow <Destroy> "removeWindowEntry ParseErrors
2291: removeFindList -2"
2292: button $buttonFrame.save -text "Save Output" \
2293: -command "saveText $gParseErrorsText"
2294: button $buttonFrame.print -text "Print Output" \
2295: -command "printText $gParseErrorsText"
2296: pack $buttonFrame.print $buttonFrame.save \
2297: $buttonFrame.ok -side left
2298:
2299: Centre_Dialog $parseErrorsWindow default
2300: update
2301: capaRaise $parseErrorsWindow
2302: } else {
2303: $gParseErrorsText delete 0.0 end
2304: capaRaise .parseErrors
2305: }
2306: foreach line [split $parseErrors "\n"] {
2307: set tag 0
2308: if { [regexp -indices {File:.+->(.+), Line ([0-9]+): ERROR:} $line result file linenum]} {
2309: set tag 1
2310: } else {
2311: if { [regexp -indices {File:(.+), Line ([0-9]+): ERROR:} $line result file linenum]} {
2312: set tag 2
2313: }
2314: }
2315: if { $tag } {
2316: set tagnum [incr gUniqueNumber]
2317: set linenum [eval [list string range $line] $linenum]
2318: set filename [eval [list string range $line] $file]
2319: set i [expr [lindex [split [$gParseErrorsText index end] .] 0] - 1]
2320: }
2321: $gParseErrorsText insert end "$line\n"
2322: if { $tag } {
2323: $gParseErrorsText tag add error.$tagnum $i.[lindex $file 0] $i.[expr [lindex $file 1] + 1]
2324: $gParseErrorsText tag configure error.$tagnum -foreground $gCapaConfig(IMP_color)
2325: $gParseErrorsText tag bind error.$tagnum <Double-ButtonPress> \
2326: "eval openError $filename $linenum $tag"
2327: }
2328: }
2329: } else {
2330: if { [winfo exists .parseErrors] } { $gParseErrorsText delete 0.0 end }
2331: }
2332:
2333: return $parseErrors
2334: }
2335:
2336: ###########################################################
2337: # printText
2338: ###########################################################
2339: # prints the contents of the text window, creates a temp file named
2340: # quiztemp.txt
2341: ###########################################################
2342: # Arguments: window (name of text window to print the contents of.
2343: # Returns : nothing
2344: # Globals :
2345: ###########################################################
2346: proc printText { window } {
2347:
2348: if { ![winfo exists $window] } {
2349: return
2350: }
2351: set lprCommand [getLprCommand quiztemp.txt]
2352:
2353: if {$lprCommand == "Cancel"} {
2354: return
2355: }
2356:
2357: set fileId [open "quiztemp.txt" w]
2358: puts -nonewline $fileId "[ $window get 0.0 end ]"
2359: close $fileId
2360:
2361: set errorMsg ""
2362: set error [catch {set output [ eval "exec $lprCommand" ] } errorMsg ]
2363:
2364: if { $error == 1 } {
2365: displayError "An error occurred while printing: $errorMsg"
2366: } else {
2367: displayMessage "Print job sent to the printer.\n $output"
2368: }
2369: exec rm -f quiztemp.txt
2370: }
2371:
2372: ###########################################################
2373: # saveText
2374: ###########################################################
2375: # saves the contents of the text window
2376: ###########################################################
2377: # Arguments: window (name of text window to save the contents of.
2378: # saveAs (whether to ask to save)
2379: # refNum (if supplied reference file unique number
2380: # that is being saved)
2381: # Returns : name of the file saved
2382: # Globals :
2383: ###########################################################
2384: proc saveText { window {saveAs 1} {refNum 0} } {
2385: global gWindowMenu gRefFile gRefChanged gCapaConfig gFile
2386:
2387: if { ![winfo exists $window] } {return}
2388: if { $refNum } {
2389: if {$saveAs} {
2390: set dir [file dirname $gRefFile($refNum)]
2391: set file ""
2392: } else {
2393: set dir [file dirname $gRefFile($refNum)]
2394: set file [file tail $gRefFile($refNum)]
2395: }
2396: } else { set dir [ set file "" ] }
2397: # if { $dir == "" || $dir == "."} { set dir [pwd] }
2398: if { $file == "" } {
2399: set file [tk_getSaveFile -title "Enter the name to Save As" \
2400: -initialdir "$dir" ]
2401: if { $file == "" } {
2402: displayError "File not saved"
2403: return
2404: }
2405: } else {
2406: set file [file join $dir $file]
2407: }
2408:
2409: if { $refNum } {
2410: catch {removeWindowEntry "Reference $gRefFile($refNum)*" }
2411: catch {removeFindList $refNum}
2412: set gRefFile($refNum) $file
2413: addFindList $refNum
2414: wm title [winfo toplevel $window] $file
2415: $gWindowMenu add command -label "Reference $file" \
2416: -command "capaRaise [winfo toplevel $window]"
2417: if { !$saveAs } {
2418: if { ([array name gCapaConfig quizzerBackupRef] == "") ||
2419: ($gCapaConfig(quizzerBackupRef)!="off") } {
2420: if { [catch {file copy -force $file $file.bak} ] } {
2421: displayError "Unable to create backup for $file"
2422: }
2423: }
2424: }
2425: }
2426: set fileId [open $file w]
2427: puts -nonewline $fileId [$window get 0.0 end]
2428: close $fileId
2429: if { $refNum } { set gRefChanged($refNum) 0 }
2430: if { ([file tail $file] == "capa.config") && ($dir == [file dirname $gFile]) } {
2431: if { [makeSure "Reread capa.config settings into Quizzer?"] != "Cancel" } {
2432: rereadCapaConfig
2433: }
2434: }
2435:
2436: return $file
2437: }
2438:
2439: ###########################################################
2440: # deleteFile
2441: ###########################################################
2442: ###########################################################
2443: ###########################################################
2444: proc deleteFile { which } {
2445: global gFile gRefFile
2446: if { $which } { set file $gRefFile($which) } else { set file $gFile }
2447: if { [makeSure "Do you wish to Delete $file"] == "Cancel" } { return }
2448: if { $which } { closeRefFile $which 1 0 } else { closeDocument 1 0 }
2449: file delete -- $file
2450: }
2451:
2452: ###########################################################
2453: ###########################################################
2454: ###########################################################
2455: ###########################################################
2456: proc rereadCapaConfig { } {
2457: global gCapaConfig
2458: set printer_option $gCapaConfig(printer_option)
2459: unset gCapaConfig(printer_option)
2460: set error [parseCapaConfig]
2461: if { $error != "OK" } {
2462: displayError "Invalid capa.config file"
2463: set gCapaConfig(printer_option) $printer_option
2464: }
2465: setDefaultValues
2466: updateColors
2467: }
2468:
2469: ###########################################################
2470: ###########################################################
2471: ###########################################################
2472: ###########################################################
2473: proc pickCapaConfig { } {
2474: set error NOTOK
2475: while { $error != "OK" } {
2476: set file [tk_getOpenFile -title "Pick a capa.config file" \
2477: -filetypes { { {CAPA configuration} {capa.config} } \
2478: { {All Files} {*} } }]
2479: if { $file == "" } { break }
2480: set oldDir [pwd]
2481: cd [file dirname $file]
2482: set error [parseCapaConfig]
2483: if { $error != "OK" } { displayError "Invalid capa.config file"; cd $oldDir }
2484: setDefaultValues
2485: }
2486: }
2487:
2488: proc setDefaultValues {} {
2489: global gProbVal gTryVal gHintVal gCapaConfig
2490: catch {set gProbVal $gCapaConfig(default_prob_val)}
2491: catch {set gTryVal $gCapaConfig(default_try_val)}
2492: catch {set gHintVal $gCapaConfig(default_hint_val)}
2493: }
2494:
2495: ###########################################################
2496: # openDocument
2497: ###########################################################
2498: ###########################################################
2499: ###########################################################
2500: proc openDocument {} {
2501: global gFile gTextWindow gSetNumberText gPrefs gChanged gQuizTemp gUndo
2502:
2503: if { $gChanged } { if { [askToSave 0 0] == "Cancel" } { return } }
2504: if { ![catch {set gTextWindow}] } {
2505: if { [winfo exists $gTextWindow] } { return }
2506: }
2507:
2508: # the event generation is because of a bug in tk_getOpenFile
2509: # After double cliking the mouse Button one is thought to be left down.
2510: # this only seems to happen when a toplevel window is created
2511: # after getting the file
2512: set gFile [tk_getOpenFile -filetypes \
2513: { { {Quizzer} {"*.qz"} } { {All Files} {"*"} } } \
2514: -title "Select the proper file" -initialdir "[pwd]" ]
2515: # event generate .main <ButtonRelease-1>
2516: if { $gFile == "" } { return }
2517: if { [file isdirectory $gFile] } {
2518: displayError "You attempted to open $gFile which is a directory not a file."
2519: return
2520: }
2521:
2522: set error [ catch {set fileId [open $gFile r] } ]
2523:
2524: if { $error } {
2525: displayError "Unable to read $gFile"
2526: return
2527: }
2528:
2529: set oldDir [pwd]
2530:
2531: cd [file dirname $gFile]
2532:
2533: set tempfiles ""
2534: catch {set tempfiles [glob quiztemp.*]}
2535: if { $tempfiles == "" } {
2536: set gQuizTemp true
2537: }
2538: foreach quiztempFile $tempfiles {
2539: if { ! ( [file isfile $quiztempFile] &&
2540: [file writable $quiztempFile] ) } {
2541: if { [makeSure "There are old quiztemp files in this directory that can not be overwritten. If you continue editing you will be unable to print or Create .dvi. You can still preview and save."] == "Cancel" } {
2542: cd $oldDir
2543: set gQuizTemp true
2544: return
2545: } else {
2546: set gQuizTemp false
2547: break
2548: }
2549: }
2550: }
2551:
2552: if { $tempfiles == "" } {
2553: if { ! [file writable $gFile] } {
2554: if { [makeSure "You do not have permission to write to this directory. If you continue editing you will be unable to save, print, or create .dvi"] == "Cancel" } {
2555: cd $oldDir
2556: set gQuizTemp true
2557: return
2558: } else {
2559: set gQuizTemp false
2560: }
2561: }
2562: }
2563:
2564: set error [parseCapaConfig]
2565:
2566: if { $error != "OK" } {
2567: cd $oldDir
2568: set gQuizTemp true
2569: return
2570: }
2571: setDefaultValues
2572:
2573: createEditingWindow 0
2574: $gTextWindow delete 0.0 end
2575: $gTextWindow insert 0.0 [read $fileId [file size $gFile]]
2576: $gTextWindow delete end-1c
2577:
2578: rename $gTextWindow .$gTextWindow
2579: trackChanges $gTextWindow 0
2580: set gUndo(0) 0
2581: set gUndo(0.cur) 0
2582:
2583: createImportLinks 0 0.0 end
2584: focus -force $gTextWindow
2585: set coord [$gTextWindow bbox 0.0]
2586: event generate $gTextWindow <1> -x [lindex $coord 0] -y [lindex $coord 1]
2587: event generate $gTextWindow <ButtonRelease-1>
2588: update
2589: close $fileId
2590:
2591: updatePrefsWindow
2592:
2593: set gSetNumberText [string range [file rootname [file tail $gFile]] 3 end ]
2594: checkIfValidFilename
2595: set gChanged 0
2596: }
2597:
2598: ###########################################################
2599: # includeReferenceFile
2600: ###########################################################
2601: ###########################################################
2602: ###########################################################
2603: proc includeReferenceFile { file num window } {
2604: set index [$window index "file.$num.first linestart"]
2605: if { ![file readable $file] } {
2606: displayError "Unable to read file $file"
2607: return
2608: }
2609: set impline [$window get $index "$index lineend"]
2610: set fileId [open $file r]
2611: $window insert $index /
2612: update idletasks
2613: if { [$window index end] == [$window index "$index + 1 lines"] } {
2614: $window insert "$index + 1 lines" "\n[read $fileId [file size $file]]"
2615: } else {
2616: $window insert "$index + 1 lines" [read $fileId [file size $file]]
2617: }
2618: close $fileId
2619: }
2620:
2621: ###########################################################
2622: # impMenuSaveAs
2623: ###########################################################
2624: ###########################################################
2625: ###########################################################
2626: proc impMenuSaveAs { file num window } {
2627: set index [$window index "file.$num.first linestart"]
2628: if { ![file readable $file] } {
2629: displayError "Unable to read file $file"
2630: return
2631: }
2632: set dir [file dirname $file]
2633: if { $dir != "." } {
2634: set dest [tk_getSaveFile -title "Enter the name to Save As" -initialdir $dir]
2635: } else {
2636: set dest [tk_getSaveFile -title "Enter the name to Save As" -initialdir [pwd]]
2637: }
2638: if { $dest == "" } {
2639: displayError "File not saved"
2640: return
2641: }
2642: if { [catch {file copy -force -- $file $dest} errorMsg ] } {
2643: displayError "Unable to copy $file to $dest: $errorMsg"
2644: return
2645: }
2646: $window delete $index "$index lineend"
2647: if { $dir != "." } {
2648: $window insert $index "/IMP \"$dest\""
2649: } else {
2650: $window insert $index "/IMP \"[file tail $dest]\""
2651: }
2652: }
2653:
2654: ###########################################################
2655: # createImpMenu
2656: ###########################################################
2657: ###########################################################
2658: ###########################################################
2659: proc createImpMenu { file num window } {
2660: set menuFrame [menu .impmenu -tearoff 0 -type tearoff ]
2661:
2662: # wm title $menuFrame "Quizzer"
2663: wm overrideredirect $menuFrame 1
2664: wm positionfrom $menuFrame program
2665: $menuFrame post [winfo pointerx .] [winfo pointery .]
2666: $menuFrame add command -label "Open" -command "openReferenceFile $file"
2667: $menuFrame add command -label "Include" -command \
2668: "includeReferenceFile $file $num $window"
2669: $menuFrame add command -label "saveAs" -command "impMenuSaveAs $file $num $window"
2670: grab $menuFrame
2671: bind all <ButtonRelease> "grab release $menuFrame;destroy $menuFrame"
2672: }
2673:
2674: ###########################################################
2675: # registerCreateImportLinks
2676: ###########################################################
2677: ###########################################################
2678: ###########################################################
2679: proc registerCreateImportLinks { num start end} {
2680: global gDoCreateImportLinks gCreateImportLinks
2681:
2682: if { $gCreateImportLinks && !$gDoCreateImportLinks($num) } {
2683: after idle "createImportLinks $num $start $end"
2684: set gDoCreateImportLinks($num) 1
2685: }
2686: }
2687:
2688: ###########################################################
2689: # createImportLinks
2690: ###########################################################
2691: ###########################################################
2692: ###########################################################
2693: proc createImportLinks { num start end } {
2694: global gTextWindow gUniqueNumber gDoCreateImportLinks gRefText gCapaConfig
2695:
2696: set gDoCreateImportLinks($num) 0
2697: if { $num } { set window $gRefText($num) } else { set window $gTextWindow }
2698: if { ![winfo exists $window] } { return }
2699: set end [$window index $end]
2700: set start [$window index $start]
2701: set lastline [lindex [split $end .] 0]
2702: set startline [lindex [split $start .] 0]
2703: foreach tag [$window tag names] {
2704: if { [regexp {file\..+} $tag ] } {
2705: if { [$window tag nextrange $tag "$start linestart" "$end lineend"] != "" } {
2706: $window tag delete $tag
2707: }
2708: }
2709: }
2710: for { set i $startline } { $i <= $lastline } { incr i } {
2711: set aline [$window get $i.0 "$i.0 lineend"]
2712: if { [regexp -nocase {(^[ ]*)(//.*)} $aline matchVar match1 match2] } {
2713: set tagnum [incr gUniqueNumber]
2714: set start [string length $match1]
2715: set end [expr $start + [string length $match2]]
2716: $window tag add file.$tagnum $i.$start $i.$end
2717: $window tag configure file.$tagnum -foreground $gCapaConfig(comment_color)
2718: } elseif { [regexp -nocase {(^.*/let.*[ ]+)(//.*)} $aline matchVar \
2719: match1 match2] } {
2720: set tagnum [incr gUniqueNumber]
2721: set start [string length $match1]
2722: set end [expr $start + [string length $match2]]
2723: $window tag add file.$tagnum $i.$start $i.$end
2724: $window tag configure file.$tagnum -foreground $gCapaConfig(comment_color)
2725: }
2726: if { [regexp -nocase "(.*/imp +)(\"\[^\"\]+\")(.*)" $aline matchVar \
2727: match1 match2 match3] } {
2728: set tagnum [incr gUniqueNumber]
2729: set start [string length $match1]
2730: set end [expr $start + [string length $match2]]
2731: $window tag add file.$tagnum $i.$start $i.$end
2732: $window tag configure file.$tagnum -foreground $gCapaConfig(IMP_color)
2733: $window tag bind file.$tagnum <Double-ButtonPress> \
2734: "eval openReferenceFile $match2"
2735: $window tag bind file.$tagnum <ButtonPress-3> \
2736: "eval createImpMenu $match2 $tagnum $window"
2737: }
2738: }
2739: }
2740:
2741: ###########################################################
2742: # isReferenceFileOpen
2743: ###########################################################
2744: ###########################################################
2745: ###########################################################
2746: proc isReferenceFileOpen { file } {
2747: global gWindowMenu
2748: # if { [catch {set index [$gWindowMenu index "Reference $file"]} ] } { return "" }
2749: set last [$gWindowMenu index end]
2750: # puts $last
2751: for { set index 1 } { $index <= $last } { incr index } {
2752: # puts $index
2753: catch {set entry [$gWindowMenu entrycget $index -label]}
2754: if { "Reference" == [set entryfile [lindex $entry 0]] } {
2755: set entryfile [lindex $entry 1]
2756: }
2757: # puts $entryfile
2758: if { [catch {file stat $entryfile a1}] } { continue }
2759: file stat $file a2
2760: # puts "$a2(ino) == $a1(ino)"
2761: if { $a2(ino) == $a1(ino) } {
2762: # puts "seems right"
2763: return [lindex [$gWindowMenu entrycget $index -command] 1]
2764: }
2765: }
2766: # puts "failed $index"
2767: return ""
2768: # puts $index
2769: # puts [$gWindowMenu entrycget $index -command]
2770: # return [lindex [$gWindowMenu entrycget $index -command] 1]
2771: }
2772:
2773: ###########################################################
2774: # newReferenceFile
2775: ###########################################################
2776: ###########################################################
2777: ###########################################################
2778: proc newReferenceFile { } {
2779: global gDir
2780: # if { $gDir(reference) == "." } { set gDir(reference) [pwd] }
2781: set file [tk_getSaveFile -title "Enter the name of the New reference file" \
2782: -initialdir "$gDir(reference)" ]
2783: event generate .main <ButtonRelease-1>
2784: if { $file == "" } { return }
2785: set gDir(reference) [file dirname $file]
2786: if { [file isdirectory $file] } {
2787: displayError "You attempted to create $file which is already a directory."
2788: return
2789: }
2790: openReferenceFile $file 1
2791: }
2792:
2793: ###########################################################
2794: # openReferenceFile
2795: ###########################################################
2796: ###########################################################
2797: ###########################################################
2798: proc openReferenceFile { {file ""} {new 0}} {
2799: global gUniqueNumber gWindowMenu gDir
2800:
2801: set num [incr gUniqueNumber]
2802: global gRefCurLine gRefLine gRefText gRefChanged gRefFile gRefClosed \
2803: gUndo gRefChangedLast
2804: # the event generation is because of a bug in tk_getOpenFile
2805: # After double cliking the mouse Button one is thought to be left down.
2806: # this only seems to happen when a toplevel window is created
2807: # after getting the file
2808: if { $file == "" } {
2809: # if { $gDir(reference) == "." } { set gDir(reference) [pwd] }
2810: set file [tk_getOpenFile -filetypes \
2811: { { {All Files} {"*"} } { {Quizzer} {"*.qz"} } } \
2812: -title "Select the proper file" \
2813: -initialdir "$gDir(reference)" ]
2814: event generate .main <ButtonRelease-1>
2815: if { $file == "" } { return 0 }
2816: set gDir(reference) [file dirname $file]
2817:
2818: if { [file isdirectory $file] } {
2819: displayError "You attempted to open $file which is a directory not a file."
2820: return 0
2821: }
2822: } else {
2823: if { !$new } {
2824: if { [set window [isReferenceFileOpen $file] ] != "" } {
2825: set num [lindex [split [lindex [split $window .] 1] e] end]
2826: capaRaise $window
2827: return $num
2828: }
2829: # specifically opening the capa.config file
2830: if { $file == "capa.config" } {
2831: global gTextWindow gFile
2832: if { [catch {set gTextWindow}] } {
2833: set file [tk_getOpenFile -filetypes \
2834: {{{Capa.config file} {"capa.config"}}
2835: { {All Files} {"*"} } } \
2836: -title "Select the proper file" \
2837: -initialdir "$gDir(reference)" ]
2838: if { $file == "" } { return 0 }
2839: } else {
2840: set file [file join [file dirname $gFile] capa.config]
2841: }
2842: } else {
2843: if { ![file isfile $file] && ![file readable $file] } {
2844: displayError "Unable to find $file"
2845: return 0
2846: }
2847: if { [file isdirectory $file] } {
2848: displayError "You attempted to open $file which is a directory not a file."
2849: return 0
2850: }
2851: }
2852: }
2853: }
2854:
2855: set gRefFile($num) $file
2856: set referenceFile [toplevel .reference$num]
2857: wm title $referenceFile "$file"
2858:
2859: $gWindowMenu add command -label "Reference $file" \
2860: -command "capaRaise $referenceFile"
2861:
2862: set menuFrame [frame $referenceFile.menu -borderwidth 3 -relief raised]
2863: set lineFrame [frame $referenceFile.lineFrame]
2864: set windowFrame [frame $referenceFile.windowFrame]
2865: pack $menuFrame $lineFrame $windowFrame
2866: pack configure $windowFrame -expand 1 -fill both
2867: pack configure $menuFrame -fill x
2868:
2869: label $lineFrame.msg -text "Current Line:"
2870: label $lineFrame.current -textvariable gRefCurLine($num)
2871: entry $lineFrame.line -width 8 -textvariable gRefLine($num)
2872: bind $lineFrame.line <KeyPress-Return> "+gotoRefLine $num"
2873: button $lineFrame.button -text "Goto" -command \
2874: "gotoRefLine $num"
2875: pack $lineFrame.msg $lineFrame.current $lineFrame.line \
2876: $lineFrame.button -side left
2877:
2878: set infoFrame [frame $windowFrame.infoFrame]
2879: set textFrame [frame $windowFrame.textFrame]
2880: pack $infoFrame $textFrame -side top
2881: pack configure $textFrame -expand 1 -fill both
2882:
2883: scrollbar $textFrame.scroll -orient vertical -command \
2884: "$textFrame.text yview"
2885: set textWindow [text $textFrame.text -yscrollcommand \
2886: "$textFrame.scroll set" -wrap char]
2887: pack $textFrame.scroll $textWindow -side left -expand 0
2888: pack configure $textFrame.scroll -expand 0 -fill y
2889: pack configure $textWindow -expand true -fill both
2890:
2891: # label $infoFrame.label -textvariable gRefFile($num)
2892: # pack $infoFrame.label -side left
2893:
2894: menubutton $menuFrame.file -text File -menu $menuFrame.file.m
2895: menubutton $menuFrame.edit -text Edit -menu $menuFrame.edit.m
2896: pack $menuFrame.file $menuFrame.edit -side left
2897:
2898: set fileMenu [ menu $menuFrame.file.m ]
2899: set editMenu [ menu $menuFrame.edit.m ]
2900:
2901: $fileMenu add command -label Save -command \
2902: "saveText $textWindow 0 $num" -accelerator "Alt+s"
2903: bind $referenceFile <Alt-s> \
2904: "saveText $textWindow 0 $num"
2905: $fileMenu add command -label "Save As" -command \
2906: "saveText $textWindow 1 $num" -accelerator "Alt+S"
2907: bind $referenceFile <Alt-Shift-s> "saveText $textWindow 1 $num"
2908: $fileMenu add command -label Delete -command "deleteFile $num"
2909: $fileMenu add command -label Print -command "printText $textWindow"
2910: $fileMenu add command -label Close -command "closeRefFile $num" \
2911: -accelerator "Alt+w"
2912: bind $referenceFile <Alt-w> "closeRefFile $num"
2913: # bind $referenceFile <Destroy> "closeRefFile $num 1"
2914: wm protocol $referenceFile WM_DELETE_WINDOW "closeRefFile $num 1"
2915: $editMenu add command -label "Cut" -command "tk_textCut $textWindow" \
2916: -accelerator "Alt+x"
2917: bind $referenceFile <Alt-x> "tk_textCut $textWindow"
2918: $editMenu add command -label "Copy" -command "tk_textCopy $textWindow" \
2919: -accelerator "Alt+c"
2920: bind $referenceFile <Alt-c> "tk_textCopy $textWindow"
2921: $editMenu add command -label "Paste" -command "tk_textPaste $textWindow" \
2922: -accelerator "Alt+v"
2923: bind $referenceFile <Alt-v> "tk_textPaste $textWindow"
2924: $editMenu add command -label "Select All " -command \
2925: "selectAll $num " -accelerator "Alt+a"
2926: bind $referenceFile <Alt-a> "selectAll $num"
2927: $editMenu add separator
2928: $editMenu add command -label "Undo" -command "undo $num" \
2929: -accelerator "Alt+u"
2930: bind $referenceFile <Alt-u> "undo $num"
2931: # $editMenu add command -label "Redo" -command "redo $num"
2932: $editMenu add separator
2933: $editMenu add command -label "Find" -command "createFindWindow $num" \
2934: -accelerator "Alt+f"
2935:
2936:
2937: if { !$new } {
2938: set fileId [open $file r]
2939: $textWindow insert 0.0 [read $fileId [file size $file]]
2940: $textWindow delete end-1c
2941: close $fileId
2942: }
2943:
2944: set gRefText($num) $textWindow
2945: rename $textWindow .$textWindow
2946: trackChanges $textWindow $num
2947: set gUndo($num) 0
2948: set gUndo($num.cur) 0
2949:
2950: createImportLinks $num 0.0 end
2951: focus -force $textWindow
2952: # update
2953: set coord [$textWindow bbox 0.0]
2954: event generate $textWindow <1> -x [lindex $coord 0] -y [lindex $coord 1]
2955: # update
2956: event generate $textWindow <ButtonRelease-1>
2957: # update
2958: # capaRaise $referenceFile
2959: after 1 "catch \{focus $textWindow;raise $referenceFile\}"
2960: selection clear
2961: #order is important here since gRefChanged has a trace on it the references
2962: #gRefChangedLast
2963: set gRefChangedLast($num) 0
2964: set gRefChanged($num) 0
2965: set gRefClosed($num) 0
2966: addFindList $num
2967: return $num
2968: }
2969:
2970: ###########################################################
2971: ###########################################################
2972: ###########################################################
2973: ###########################################################
2974: proc trackChanges { procName num } {
2975: eval "proc $procName args {
2976: global gUndo gRefChanged gChanged
2977: if {\[regexp {^(ins|del).*} \[lindex \$args 0\]\]} {
2978: #puts \"\$args\"
2979: if { \$gUndo($num.cur) != \$gUndo($num) } {
2980: set i \[expr \$gUndo($num.cur) + 1 \]
2981: while { \[ info exists gUndo($num.\$i) \] } {
2982: unset gUndo($num.\$i)
2983: incr i
2984: }
2985: set gUndo($num) \$gUndo($num.cur)
2986: }
2987: set gUndo($num.cur) \$gUndo($num)
2988: set insertindex \[.$procName index \[lindex \$args 1 \] \]
2989: set numChange \[set gUndo($num.cur) \[incr gUndo($num) \] \]
2990: if { $num == 0 } { set gChanged 1 } else { set gRefChanged($num) 1 }
2991: }
2992: if {\[regexp {^(ins).*} \[lindex \$args 0\]\]} {
2993: set index2 \$insertindex+\[string length \[lindex \$args 2 \] \]chars
2994: set gUndo($num.\$numChange) \"delete \$insertindex \$index2 \"
2995: if {\[regexp {.*\[\"/\].*} \$args\] || \
2996: \[regexp {.*\[\"/\].*} \[.$procName get \"\$insertindex linestart\" \"\$index2 lineend\"\]\]} {
2997: registerCreateImportLinks $num \$insertindex \$index2
2998: }
2999: } elseif {\[regexp {^(del).*} \[lindex \$args 0\]\]} {
3000: if { \[catch { set insertindex2 \[.$procName index \
3001: \[lindex \$args 2 \] \] } \] } {
3002: set chars \[ .$procName get \$insertindex \]
3003: set insertindex2 \$insertindex+1c
3004: } else {
3005: set chars \[ .$procName get \$insertindex \$insertindex2 \]
3006: }
3007: set gUndo($num.\$numChange) \"insert \$insertindex \[list \$chars\] \"
3008: if {\[regexp \{.*\[\"/\].*\} \$chars\] || \
3009: \[regexp \{.*\[\"/\].*\} \[.$procName get \"\$insertindex linestart\" \"\$insertindex2 lineend\"\]\]} {
3010: registerCreateImportLinks $num \$insertindex \$insertindex2
3011: }
3012: }
3013: set result \[uplevel .$procName \$args\]
3014: updateLocation $num
3015: return \$result
3016: }"
3017: }
3018:
3019: ###########################################################
3020: ###########################################################
3021: ###########################################################
3022: ###########################################################
3023: proc undo { num } {
3024: global gUndo gRefText gTextWindow gChanged gRefChanged
3025: if { $gUndo($num.cur) == 0 } { return }
3026: set undoInfo $gUndo($num.$gUndo($num.cur))
3027: if { [regexp {.*[\"/].*} $undoInfo] } {
3028: registerCreateImportLinks $num [lindex $undoInfo 1] end
3029: }
3030: if { [regexp {.*delete.*} $undoInfo] } {
3031: registerCreateImportLinks $num [lindex $undoInfo 1] [lindex $undoInfo 2]
3032: }
3033: if { $num == 0 } {
3034: if {[catch {eval ".$gTextWindow $gUndo($num.$gUndo($num.cur))"}]} { return }
3035: set gChanged 1
3036: } else {
3037: if {[catch {eval ".$gRefText($num) $gUndo($num.$gUndo($num.cur))"}]} { return }
3038: set gRefChanged($num) 1
3039: }
3040: incr gUndo($num.cur) -1
3041: }
3042:
3043: ###########################################################
3044: ###########################################################
3045: ###########################################################
3046: ###########################################################
3047: proc redo { num } {
3048: global gUndo gRefText
3049: }
3050:
3051: ###########################################################
3052: ###########################################################
3053: ###########################################################
3054: ###########################################################
3055: proc gotoRefLine { number } {
3056: global gRefLine gRefText
3057: if { [catch {set gRefText($number)}] } { return }
3058: if { ![winfo exists $gRefText($number)] } { return }
3059:
3060: if { $gRefLine($number) == "" } {
3061: return
3062: } else {
3063: $gRefText($number) mark set insert $gRefLine($number).0
3064: catch {$gRefText($number) tag remove sel sel.first sel.last}
3065: $gRefText($number) tag add sel "insert linestart" "insert lineend"
3066: $gRefText($number) see insert
3067: }
3068: }
3069:
3070: ###########################################################
3071: # updateLocation
3072: ###########################################################
3073: ###########################################################
3074: ###########################################################
3075: proc updateLocation { number } {
3076: global gRefCurLine gRefText gTextWindow gLineNumber gCharacterNumber
3077:
3078: if {$number} {set window $gRefText($number)} {set window $gTextWindow}
3079: # if {![winfo exists $gRefText($number)]} {return};#do I need this
3080: set spot [split [.$window index insert] "."]
3081: if { $number } {
3082: set gRefCurLine($number) [lindex $spot 0 ]
3083: } else {
3084: set gLineNumber [lindex $spot 0]
3085: set gCharacterNumber [lindex $spot 0]
3086: }
3087: }
3088:
3089: ###########################################################
3090: ###########################################################
3091: ###########################################################
3092: ###########################################################
3093: proc askToSave { refNum mustClose } {
3094: global gPrompt
3095:
3096: set dialog [toplevel .askToSavePrompt -borderwidth 10]
3097: wm title $dialog "Do you wish to Save"
3098: wm geo $dialog "+200+200"
3099: if { $refNum } {
3100: global gRefFile
3101: set msg "Reference File: $gRefFile($refNum) has changed. Do you wish to save?"
3102: } else {
3103: set msg "Source has changed do you wish to save?"
3104: }
3105: message $dialog.msg -text $msg -aspect 800
3106:
3107: set gPrompt(result) ""
3108: set buttonFrame [frame $dialog.buttons -bd 10]
3109: pack $dialog.msg $buttonFrame -side top -fill x
3110:
3111: bind $dialog <Destroy> {
3112: set gPrompt(result) Cancel
3113: set gPrompt(yes) 0
3114: }
3115:
3116: button $buttonFrame.yes -text Yes -underline 0 -command {
3117: set gPrompt(yes) 1
3118: }
3119: button $buttonFrame.no -text No -underline 0 -command {
3120: set gPrompt(yes) 0
3121: }
3122: if { !$mustClose } {
3123: button $buttonFrame.cancel -text Cancel -underline 0 -command {
3124: set gPrompt(yes) 0
3125: set gPrompt(result) Cancel
3126: }
3127: pack $buttonFrame.yes $buttonFrame.no $buttonFrame.cancel -side left
3128: } else {
3129: pack $buttonFrame.yes $buttonFrame.no -side left
3130: }
3131: bind $dialog <Alt-Key> break
3132:
3133: Centre_Dialog $dialog default
3134: update
3135:
3136: focus $dialog
3137: capaRaise $dialog
3138: capaGrab $dialog
3139: vwait gPrompt(yes)
3140: capaGrab release $dialog
3141: bind $dialog <Destroy> ""
3142: destroy $dialog
3143: if {$gPrompt(yes)} {
3144: if { $refNum } {
3145: global gRefText
3146: saveText $gRefText($refNum) 0 $refNum
3147: } else {
3148: saveDocument
3149: }
3150: } else {
3151: return $gPrompt(result)
3152: }
3153: }
3154:
3155: ###########################################################
3156: ###########################################################
3157: ###########################################################
3158: ###########################################################
3159: proc saveDocument { {saveAs 0} } {
3160: global gFile gTextWindow gSetNumberText gChanged gEditWindow gWindowMenu \
3161: gCapaConfig
3162: if { [catch {set gTextWindow}] } { return }
3163: if { ![winfo exists $gTextWindow] } { return }
3164: if { $gFile == "" } { set saveAs 1 }
3165: if {$saveAs == 1} {
3166: set temp [tk_getSaveFile -title "Enter the name to Save As" \
3167: -initialdir "[pwd]" ]
3168: if { $temp == "" } {
3169: displayError "File not saved"
3170: return
3171: }
3172:
3173: catch {removeWindowEntry "$gFile*"}
3174: catch {removeFindList}
3175: set gFile $temp
3176: addFindList
3177: cd [file dirname $gFile]
3178: set gSetNumberText [string range [file rootname [file tail $gFile]] \
3179: 3 end ]
3180: checkIfValidFilename
3181: wm title [winfo toplevel $gEditWindow] $gFile
3182:
3183: $gWindowMenu add command -label "$gFile" -command \
3184: "capaRaise $gEditWindow"
3185: } else {
3186: if { ([array name gCapaConfig quizzerBackupQZ] == "") ||
3187: ($gCapaConfig(quizzerBackupQZ)!="off") } {
3188: if { [catch {file copy -force $gFile $gFile.bak} ] } {
3189: displayError "Unable to create backup for $gFile"
3190: }
3191: }
3192: }
3193:
3194: set fileId [open $gFile w]
3195:
3196: puts -nonewline $fileId [$gTextWindow get 0.0 end]
3197:
3198: close $fileId
3199:
3200: savePrefs
3201: set gChanged 0
3202: }
3203:
3204: ###########################################################
3205: ###########################################################
3206: ###########################################################
3207: ###########################################################
3208: proc closeDocument { { mustClose 0 } { save 1 } } {
3209: global gFile gEditWindow gChanged gPrefs \
3210: gPutLine gTryVal gProbVal gHintVal gQuizTemp \
3211: gNumberParsedText gSetNumberText gClosedDocument gTextWindow
3212: if { [catch {set gEditWindow}] } { return }
3213: if { ![winfo exists $gEditWindow] } { return }
3214: if { $gClosedDocument } { return }
3215: if { $save && $gChanged } {
3216: if { [askToSave 0 $mustClose] == "Cancel" && (! $mustClose ) } { return }
3217: }
3218: if {(!$mustClose)&&[makeSure "Are you sure you wish to stop editing?"]=="Cancel"} {
3219: return
3220: }
3221: set gClosedDocument 1
3222: removeFindList
3223: destroy $gEditWindow
3224: removeWindowEntry "$gFile*"
3225: set gFile ""
3226: set gChanged 0
3227: set gPrefs(info) "Problem"
3228: set gPrefs(TeXHeader) ""
3229: set gPrefs(TeXFooter) ""
3230: set gPutLine 1
3231: set gTryVal 99
3232: set gHintVal 1
3233: set gProbVal 1
3234: set gQuizTemp "true"
3235: set gNumberParsedText ""
3236: set gSetNumberText ""
3237: }
3238:
3239: ###########################################################
3240: ###########################################################
3241: ###########################################################
3242: ###########################################################
3243: proc closeRefFile { refNum { mustClose 0 } { save 1 } } {
3244: global gRefChanged gRefText gRefFile gRefClosed gRefCurLine gRefLine gRefChangedLast
3245: if { [catch {set gRefText($refNum)}] } { return }
3246: if { ![winfo exists $gRefText($refNum)] } { return }
3247: if { $gRefClosed($refNum) } { return }
3248: if { $save && $gRefChanged($refNum) } {
3249: if { [askToSave $refNum $mustClose] == "Cancel" && ( ! $mustClose ) } { return }
3250: }
3251:
3252: if { ( ! $mustClose ) && ( [makeSure "Are you sure you wish to stop editing $gRefFile($refNum)?"] == "Cancel" ) } {
3253: return
3254: }
3255: set gRefClosed($refNum) 1
3256: removeFindList $refNum
3257: destroy [winfo toplevel $gRefText($refNum)]
3258: removeWindowEntry "Reference $gRefFile($refNum)*"
3259: unset gRefText($refNum) gRefChanged($refNum) gRefClosed($refNum) gRefFile($refNum) \
3260: gRefCurLine($refNum) gRefLine($refNum) gRefChangedLast($refNum)
3261: }
3262:
3263: ###########################################################
3264: # quit
3265: ###########################################################
3266: # called when the quit option is selected on the menu, unmaps
3267: # all keys.
3268: ###########################################################
3269: # Arguments: None
3270: # Returns: Nothing
3271: # Globals: gChanged - whether or not the file has been modified
3272: ###########################################################
3273: proc quit { { mustClose 0 } } {
3274: global gChanged gRefChanged gRefText
3275:
3276: if { (! $mustClose ) && [makeSure "Are you sure you wish to quit?"] == "Cancel" } {
3277: return
3278: }
3279:
3280: if { $gChanged } {
3281: if { [askToSave 0 $mustClose] == "Cancel" && ( ! $mustClose ) } {
3282: return
3283: }
3284: }
3285:
3286: foreach refNum [array names gRefChanged] {
3287: if { $gRefChanged($refNum) == 1 } {
3288: if { [winfo exists $gRefText($refNum)] } {
3289: if { [askToSave $refNum $mustClose ] == "Cancel" && (! $mustClose ) } {
3290: return
3291: }
3292: }
3293: }
3294: }
3295:
3296: exec /bin/rm -f quiztemp.ps
3297: exec /bin/rm -f quiztemp.dvi
3298: exec /bin/rm -f quiztemp.tex
3299: exec /bin/rm -f quiztemp.log
3300: exec /bin/rm -f quiztemp.aux
3301: exec /bin/rm -f quiztemp.txt
3302:
3303: unmapAllKeys
3304:
3305: exit
3306: }
3307:
3308: ###########################################################
3309: # createStopButton
3310: ###########################################################
3311: ###########################################################
3312: ###########################################################
3313: proc createStopButton {} {
3314: global gStopStatus
3315: if {[winfo exists .stopbutton]} {destroy .stopbutton}
3316: set top [toplevel .stopbutton]
3317: button $top.stop -text "Stop Parser" -command "stopParser"
3318: label $top.status -textvariable gStopStatus -width 35 -anchor w
3319: pack $top.stop $top.status
3320: set gStopStatus ""
3321: grab $top
3322: Centre_Dialog $top default
3323: update
3324: }
3325:
3326: ###########################################################
3327: # destroyStopButton
3328: ###########################################################
3329: ###########################################################
3330: ###########################################################
3331: proc destroyStopButton {} {
3332: grab release .stopbutton
3333: destroy .stopbutton
3334: }
3335:
3336: ###########################################################
3337: # createDvi
3338: ###########################################################
3339: ###########################################################
3340: ###########################################################
3341: proc createDvi { {showXdvi 1} {showStopButton 0} {useqzparse 0}} {
3342: global gPreviewMode gCreateDviText gPrefs gSetNumberText \
3343: gStudentSelection gFile gWindowMenu gLatexId gParseErrorsText \
3344: gEditWindow gCreateDviTextTemp gXdviOpt \
3345: gLoadHeaderSet gCapaConfig gControlDates gNumberParsedText \
3346: gDonePrinting
3347:
3348: if { [catch {set gEditWindow}] } { return }
3349: if { ![winfo exists $gEditWindow] } { return }
3350:
3351: catch { destroy .createDviText }
3352: set gCreateDviTextTemp [text .createDviText]
3353:
3354: switch $gPrefs(info) {
3355: Problem { set type 0 }
3356: ProblemAnswer { set type 1 }
3357: Answer { set type 2 }
3358: }
3359:
3360: if { $useqzparse } {
3361: set gDonePrinting 0
3362: switch $gPrefs(info) {
3363: Problem { set type "-T" }
3364: Answer { set type "-Ta" }
3365: ProblemAnswer { set type "-Tb" }
3366: default { set type "-T" }
3367: }
3368: createCreateDviWin
3369: grab .createDvi
3370: $gCreateDviText delete 0.0 end
3371: if { [setupSetsToPrint set start end 0] == 1 } { return 1 }
3372: if { [set gStopPrinting [expr 2 == [runLatex \
3373: "echo [pwd] | $gCapaConfig(qzparse_command) \
3374: -stu $gStudentSelection(studentNumber) -set $set \
3375: -d [pwd] -c [pwd] $type " gCreateDviText] ] ] } {
3376: exec rm -f $gStudentSelection(studentNumber).tex quiztemp.tex
3377: if {$showStopping} {
3378: displayMessage "Printing has been stopped."
3379: set gDonePrinting 1
3380: set gStopPrinting 0
3381: }
3382: return 1
3383: }
3384: exec mv $gStudentSelection(studentNumber).tex quiztemp.tex
3385: exec /bin/rm -f quiztemp.dvi
3386: } else {
3387: createStopButton
3388: if { [catch {
3389: set numberParsed [ texParse $type $gSetNumberText \
3390: $gStudentSelection(type) $gStudentSelection(random) \
3391: $gStudentSelection(studentNumber) \
3392: $gStudentSelection(studentName) \
3393: gCreateDviTextTemp 1 ] }]} {
3394: return
3395: }
3396: destroyStopButton
3397: checkHeader $numberParsed
3398:
3399: if { [showParseErrors] != "" } {
3400: if { [makeSure "There were errors when parsing the .qz file, \
3401: continue to create the .dvi?"] =="Cancel" } {
3402: destroy $gCreateDviTextTemp
3403: return
3404: }
3405: }
3406:
3407: set error [catch { set fileId [open quiztemp.tex w] } ]
3408: if { $error } {
3409: displayError "Unable to create neccessary temp files, delete all the\
3410: quiztemp file from the class directory."
3411: return
3412: }
3413:
3414: set filename [file join [file dirname $gFile] TeXheader ]
3415: set texfileId [open $filename r]
3416: puts -nonewline $fileId [read $texfileId [file size $filename]]
3417: close $texfileId
3418:
3419: puts -nonewline $fileId "[$gCreateDviTextTemp get 0.0 end]"
3420:
3421: set filename [file join [file dirname $gFile] TeXfooter ]
3422: set texfileId [open $filename r]
3423: puts $fileId [read $texfileId [file size $filename]]
3424: close $texfileId
3425:
3426: close $fileId
3427: }
3428:
3429: destroy $gCreateDviTextTemp
3430:
3431: if { ![winfo exists .createDvi] } {
3432: set createDviWindow [toplevel .createDvi]
3433: $gWindowMenu add command -label "CreateDvi" -command \
3434: "capaRaise $createDviWindow"
3435: wm title $createDviWindow "LaTeX Output"
3436: addFindList -3
3437:
3438: set windowFrame [frame $createDviWindow.windowFrame]
3439: set buttonFrame [frame $createDviWindow.buttonFrame]
3440:
3441: pack $windowFrame $buttonFrame -side bottom
3442: pack configure $windowFrame -expand true -fill both
3443: pack configure $buttonFrame -anchor e
3444:
3445: scrollbar $windowFrame.scroll -orient vertical -command \
3446: "$windowFrame.text yview"
3447: set gCreateDviText [text $windowFrame.text -yscrollcommand \
3448: "$windowFrame.scroll set" -wrap char -height 40]
3449:
3450: pack $windowFrame.scroll $gCreateDviText -side left -expand 0
3451: pack configure $windowFrame.scroll -expand 0 -fill y
3452: pack configure $gCreateDviText -expand true -fill both
3453:
3454: set appearingFrame [frame $buttonFrame.appearingFrame]
3455: button $buttonFrame.ok -text Dismiss -command \
3456: "trace vdelete gFile w updateCreateDvi
3457: destroy $createDviWindow
3458: removeWindowEntry CreateDvi
3459: removeFindList -3"
3460: bind $createDviWindow <Destroy> \
3461: "trace vdelete gFile w updateCreateDvi
3462: removeWindowEntry CreateDvi
3463: removeFindList -3"
3464: pack $appearingFrame $buttonFrame.ok -side left
3465:
3466: button $appearingFrame.stop -text "Stop Creating Print Jobs"\
3467: -command "stopPrinting"
3468: set name [file rootname [file tail $gFile ] ].dvi
3469: button $appearingFrame.print -text \
3470: "Save.dvi file to $name" \
3471: -command saveDvi
3472: trace variable gFile w updateCreateDvi
3473:
3474: if { $showStopButton } {
3475: pack $appearingFrame.stop $appearingFrame.print -side left
3476: pack forget $appearingFrame.print
3477: } else {
3478: pack $appearingFrame.stop $appearingFrame.print -side left
3479: pack forget $appearingFrame.stop
3480: }
3481:
3482: Centre_Dialog $createDviWindow default
3483: update
3484: } else {
3485: if { $showStopButton } {
3486: pack forget .createDvi.buttonFrame.appearingFrame.print
3487: pack .createDvi.buttonFrame.appearingFrame.stop
3488: } else {
3489: pack forget .createDvi.buttonFrame.appearingFrame.stop
3490: pack .createDvi.buttonFrame.appearingFrame.print
3491: }
3492: if { !$useqzparse } { $gCreateDviText delete 0.0 end }
3493: }
3494:
3495: exec /bin/rm -f quiztemp.dvi
3496: $gCreateDviText insert end "$gCapaConfig(latex_command)\n"
3497: $gCreateDviText see end
3498: set createdDvi [ runLatex "pwd ; $gCapaConfig(latex_command) quiztemp.tex < \
3499: [file join / dev null ]" gCreateDviText]
3500:
3501: if { ($showXdvi == 1) && ( $createdDvi == 1 ) } {
3502: eval "exec $gCapaConfig(xdvi_command) $gXdviOpt quiztemp.dvi >& /dev/null & "
3503: }
3504:
3505: catch { capaRaise $gParseErrorsText }
3506: set gDonePrinting 1
3507: return $createdDvi
3508: }
3509:
3510: ###########################################################
3511: ###########################################################
3512: ###########################################################
3513: ###########################################################
3514: proc stopPrinting {} {
3515: global gStopPrinting
3516: set gStopPrinting 1
3517: }
3518:
3519: ###########################################################
3520: ###########################################################
3521: ###########################################################
3522: ###########################################################
3523: proc saveDvi { } {
3524: global gFile
3525:
3526: set name [file rootname [ file tail $gFile]].dvi
3527: catch { exec rm -f $name }
3528:
3529: if { [ catch { exec cp quiztemp.dvi $name } ] } {
3530: displayMessage "Unable to create $name "
3531: } else {
3532: displayMessage "Created $name "
3533: }
3534: }
3535:
3536:
3537: ###########################################################
3538: ###########################################################
3539: ###########################################################
3540: ###########################################################
3541: proc updateCreateDvi { name1 name2 op } {
3542: global gFile
3543:
3544: set name [file rootname [file tail $gFile ] ].dvi
3545: catch { .createDvi.buttonFrame.appearingFrame.print configure \
3546: -text "Save.dvi file to $name" }
3547: }
3548: ###########################################################
3549: ###########################################################
3550: ###########################################################
3551: ###########################################################
3552: proc printWindow {} {
3553: global gPrintSelection gWindowMenu gEditWindow gStopPrinting\
3554: gSetNumberText gMaxSet gFile gChanged
3555:
3556: set gStopPrinting 0
3557: if { [catch {set gEditWindow}] } { return }
3558: if { ![winfo exists $gEditWindow] } { return }
3559:
3560: if { [winfo exists .print] } {
3561: capaRaise .print
3562: return
3563: }
3564: if { $gChanged } { if { [askToSave 0 0] == "Cancel" } { return } }
3565:
3566: set print [toplevel .print]
3567: $gWindowMenu add command -label "Print" -command "capaRaise $print"
3568: wm title $print "Select a Print Method"
3569: message $print.msg -text "Please specify a print method." -aspect 10000
3570: set oneSetFrame [frame $print.frame1 -relief groove -borderwidth 4]
3571: set moreSetFrame [frame $print.frame2 -relief groove -borderwidth 4]
3572: set buttonFrame [frame $print.buttons]
3573: pack $print.msg $oneSetFrame $moreSetFrame $buttonFrame -side top
3574: pack configure $oneSetFrame $moreSetFrame -anchor w -fill x
3575:
3576: set infoFrame [frame $moreSetFrame.frame1]
3577: set setFrame [frame $moreSetFrame.frame2 -relief solid -borderwidth 1]
3578: pack $infoFrame $setFrame
3579: pack configure $infoFrame $setFrame -anchor w
3580:
3581: if {[catch {set gPrintSelection(sets)}]} {set gPrintSelection(sets) printCur}
3582: if {[catch {set gPrintSelection(type)}]} {set gPrintSelection(type) printSpecific}
3583: if {[catch {set gPrintSelection(setend)}]} {set gPrintSelection(setend) $gSetNumberText}
3584: radiobutton $setFrame.specific -text "Print Current Set ($gSetNumberText)" \
3585: -value "printCur" -variable gPrintSelection(sets)
3586: set scaleFrame [frame $setFrame.scales]
3587: pack $setFrame.specific $scaleFrame -anchor w
3588:
3589: for { set i 1 } { $i <= $gMaxSet } { incr i } {
3590: if { ! [file exists [file join [file dirname $gFile] records "set$i.db"]] } { break }
3591: }
3592: incr i -1
3593: set gPrintSelection(setend) $gSetNumberText
3594: radiobutton $scaleFrame.range -text "Print Set Range:" \
3595: -value "printRange" -variable gPrintSelection(sets)
3596: scale $scaleFrame.start -from 1 -to $i -variable gPrintSelection(setstart) \
3597: -orient h
3598: label $scaleFrame.msg -text "to"
3599: scale $scaleFrame.end -from 1 -to $i -variable gPrintSelection(setend) \
3600: -orient h
3601: pack $scaleFrame.range $scaleFrame.start $scaleFrame.msg \
3602: $scaleFrame.end -side left
3603:
3604: button $buttonFrame.ok -text "Select" -command selectedPrintMethod
3605: button $buttonFrame.cancel -text "Cancel" -command \
3606: "destroy .print
3607: removeWindowEntry Print"
3608: bind $print <Destroy> "removeWindowEntry Print"
3609: pack $buttonFrame.ok $buttonFrame.cancel -side left
3610:
3611: set currentDviFrame [frame $oneSetFrame.currentDvi]
3612: set currentPreviewFrame [frame $oneSetFrame.currentPreview]
3613: set randomFrame [frame $oneSetFrame.random]
3614: set specificFrame [frame $infoFrame.specific]
3615: set sectionFrame [frame $infoFrame.section]
3616: set multSectionFrame [frame $infoFrame.multsection]
3617: set wholeClassFrame [frame $infoFrame.wholeClass]
3618: pack $currentDviFrame $currentPreviewFrame $randomFrame $specificFrame \
3619: $sectionFrame $multSectionFrame $wholeClassFrame -anchor w \
3620: -side top
3621: pack configure $specificFrame -expand true -fill both
3622:
3623: radiobutton $currentDviFrame.currentDvi -text "Print current .dvi" \
3624: -value "printCurrentDvi" -variable gPrintSelection(type)
3625: pack $currentDviFrame.currentDvi -side left
3626:
3627: radiobutton $randomFrame.random -text \
3628: "Randomly select one student from section:" \
3629: -value "printRandom" -variable gPrintSelection(type)
3630: entry $randomFrame.entry -textvariable gPrintSelection(random) -width 3 \
3631: -validate key -validatecommand "limitEntry %W 3 number %P"
3632: pack $randomFrame.random $randomFrame.entry -side left
3633:
3634: radiobutton $specificFrame.specific -text "Specify the student by:" \
3635: -value "printSpecific" -variable gPrintSelection(type)
3636: set studentNumber [frame $specificFrame.studentNumber]
3637: set fullName [frame $specificFrame.fullName]
3638: pack $specificFrame.specific $studentNumber $fullName -side top
3639: pack configure $specificFrame.specific -anchor w
3640: pack configure $studentNumber $fullName -anchor e
3641:
3642: radiobutton $sectionFrame.section -text "Print section" \
3643: -value "printSection" -variable gPrintSelection(type)
3644: entry $sectionFrame.entry -textvariable gPrintSelection(section) -width 3 \
3645: -validate key -validatecommand "limitEntry %W 3 number %P"
3646: pack $sectionFrame.section $sectionFrame.entry -side left
3647:
3648: radiobutton $multSectionFrame.section -text "Print multiple sections" \
3649: -value "printMultipleSections" -variable gPrintSelection(type)
3650: pack $multSectionFrame.section -side left
3651:
3652: radiobutton $wholeClassFrame.wholeClass -text "Print whole class." \
3653: -value "printWholeClass" -variable gPrintSelection(type)
3654: pack $wholeClassFrame.wholeClass -side left
3655:
3656: message $studentNumber.msg -text "Student Number: " -aspect 10000
3657: entry $studentNumber.entry -textvariable gPrintSelection(studentNumber) -width 9 \
3658: -validate key -validatecommand "limitEntry %W 9 any %P"
3659: pack $studentNumber.msg $studentNumber.entry -side left
3660:
3661: message $fullName.msg -text "Student Name: " -aspect 10000
3662: entry $fullName.entry -textvariable gPrintSelection(studentName) -width 30 \
3663: -validate key -validatecommand "limitEntry %W 30 any %P"
3664: pack $fullName.msg $fullName.entry -side left
3665:
3666: trace variable gPrintSelection(studentNumber) w \
3667: "global gPrintSelection; set gPrintSelection(type) printSpecific ;#"
3668: trace variable gPrintSelection(studentName) w \
3669: "global gPrintSelection; set gPrintSelection(type) printSpecific ;#"
3670:
3671: # puts "trace info:[trace vinfo gPrintSelection(studentNumber)]"
3672:
3673: bind $studentNumber.entry <KeyPress-Return> \
3674: "fillInStudent gPrintSelection(studentName) gPrintSelection(studentNumber) 0"
3675: bind $fullName.entry <KeyPress-Return> \
3676: "fillInStudent gPrintSelection(studentName) gPrintSelection(studentNumber) 1"
3677:
3678:
3679: #Disable the entry boxes that are not selected, and enable the
3680: #ones that are
3681: # $specificFrame.specific configure -command "
3682: # $studentNumber.entry configure -state normal
3683: # $fullName.entry configure -state normal"
3684: # $randomFrame.random configure -command "
3685: # $studentNumber.entry configure -state disabled
3686: # $fullName.entry configure -state disabled"
3687:
3688: #If the window had been called up before we need to check the state
3689: #of the variable and disable/enable the correct enry boxes
3690: # if { $gPrintSelection(type) == "printSpecific" } {
3691: # $studentNumber.entry configure -state normal
3692: # $fullName.entry configure -state normal
3693: # }
3694: # if { $gPrintSelection(type) == "printRandom" } {
3695: # $studentNumber.entry configure -state disabled
3696: # $fullName.entry configure -state disabled
3697: # }
3698:
3699: Centre_Dialog $print default
3700: }
3701:
3702: proc selectedPrintMethod {} {
3703: global gStopPrinting gPrintSelection gStudentSelection
3704:
3705: switch $gPrintSelection(type) {
3706: printSpecific {
3707: if { $gPrintSelection(studentNumber) == "" } {
3708: displayError "You must specify a student number."
3709: return
3710: }
3711: }
3712: printSection {
3713: if { $gPrintSelection(section)== "" } {
3714: displayError "You must specify a section."
3715: return
3716: }
3717: }
3718: default {}
3719: }
3720:
3721: destroy .print
3722: removeWindowEntry Print
3723: [set gPrintSelection(type)]
3724: set gStopPrinting 0
3725: }
3726:
3727: ###########################################################
3728: # createCreateDviWin
3729: ###########################################################
3730: ###########################################################
3731: ###########################################################
3732: proc createCreateDviWin {} {
3733: global gWindowMenu gFile gCreateDviText
3734: if { ![winfo exists .createDvi] } {
3735: set createDviWindow [toplevel .createDvi]
3736: $gWindowMenu add command -label "CreateDvi" -command \
3737: "capaRaise $createDviWindow"
3738: wm title $createDviWindow "LaTeX Output"
3739:
3740: set windowFrame [frame $createDviWindow.windowFrame]
3741: set buttonFrame [frame $createDviWindow.buttonFrame]
3742:
3743: pack $windowFrame $buttonFrame -side bottom
3744: pack configure $windowFrame -expand true -fill both
3745: pack configure $buttonFrame -anchor e
3746:
3747: scrollbar $windowFrame.scroll -orient vertical -command \
3748: "$windowFrame.text yview"
3749: set gCreateDviText [text $windowFrame.text -yscrollcommand \
3750: "$windowFrame.scroll set" -wrap char -height 40]
3751:
3752: pack $windowFrame.scroll $gCreateDviText -side left -expand 0
3753: pack configure $windowFrame.scroll -expand 0 -fill y
3754: pack configure $gCreateDviText -expand true -fill both
3755:
3756: set appearingFrame [frame $buttonFrame.appearingFrame]
3757: button $buttonFrame.ok -text Dismiss -command \
3758: "checkDestroyPrint $createDviWindow"
3759: wm protocol $createDviWindow WM_DELETE_WINDOW \
3760: "checkDestroyPrint $createDviWindow"
3761: pack $appearingFrame $buttonFrame.ok -side left
3762:
3763: button $appearingFrame.stop -text "Stop Creating Print Jobs"\
3764: -command "stopPrinting"
3765: set name [file rootname [file tail $gFile ] ].dvi
3766: button $appearingFrame.print -text \
3767: "Save.dvi file to $name" \
3768: -command saveDvi
3769: trace variable gFile w updateCreateDvi
3770:
3771: pack $appearingFrame.stop $appearingFrame.print -side left
3772: pack forget $appearingFrame.print
3773:
3774: Centre_Dialog $createDviWindow default
3775: update
3776: } else {
3777: pack forget .createDvi.buttonFrame.appearingFrame.print
3778: pack .createDvi.buttonFrame.appearingFrame.stop
3779: }
3780: }
3781:
3782: ###########################################################
3783: # printBody
3784: ###########################################################
3785: # sends the file quiztemp.ps to the printer through lpr using
3786: # the option foud in gLprCommand
3787: ###########################################################
3788: # Arguments: none
3789: # Returns: Nothing
3790: # Globals: gCapaConfig -
3791: # gStopPrinting -
3792: # Files: quiztemp.ps - file containg info to print (removed)
3793: ###########################################################
3794: proc printBody { lprCommand { showCompletionMessage 1 } } {
3795: global gCapaConfig gStopPrinting gDonePrinting
3796:
3797: set errorMsg ""
3798: set error [ catch {exec $gCapaConfig(dvips_command) quiztemp.dvi \
3799: -o quiztemp.ps >& /dev/null} errorMsg ]
3800: if { $error } {
3801: displayError \
3802: "When attempting to run dvips an error occured : $errorMsg"
3803: return 1
3804: }
3805:
3806: if { $gStopPrinting } {
3807: displayMessage "Printing has been stopped."
3808: set gStopPrinting 0
3809: set gDonePrinting 1
3810: return 1
3811: }
3812:
3813: set errorMsg
3814: set error [catch {set returnMessage [eval "exec $lprCommand"] } errorMsg ]
3815:
3816: if { $error == 1 } {
3817: displayError "When attempting to print an error occured : $errorMsg"
3818: return 1
3819: } else {
3820: if { $showCompletionMessage } {
3821: displayMessage "Print job sent to the printer.\n $returnMessage"
3822: }
3823: }
3824:
3825: return 0
3826: }
3827:
3828:
3829:
3830: ###########################################################
3831: ###########################################################
3832: ###########################################################
3833: ###########################################################
3834: proc printCurrentDvi {} {
3835:
3836: set lprCommand [getLprCommand quiztemp.ps]
3837:
3838: if {$lprCommand == ""} {
3839: displayError "You must at least specify a print queue for lpr. \
3840: Nothing printed."
3841: return
3842: }
3843:
3844: if {$lprCommand == "Cancel"} {
3845: return
3846: }
3847:
3848: printBody $lprCommand
3849:
3850: return 0
3851: }
3852:
3853: ###########################################################
3854: ###########################################################
3855: ###########################################################
3856: ###########################################################
3857: proc printCurrentPreview {} {
3858:
3859: set lprCommand [getLprCommand quiztemp.ps]
3860:
3861: if {$lprCommand == ""} {
3862: displayError "You must at least specify a print queue for lpr. \
3863: Nothing printed."
3864: return
3865: }
3866:
3867: if {$lprCommand == "Cancel"} {
3868: return
3869: }
3870:
3871: if { [createDvi 0] == 2 } {
3872: displayMessage "Printing has been stopped"
3873: }
3874:
3875: printBody $lprCommand
3876:
3877: return 0
3878: }
3879:
3880: ###########################################################
3881: ###########################################################
3882: ###########################################################
3883: ###########################################################
3884: proc printRandom {} {
3885: global gStudentSelection gPrintSelection
3886:
3887: set lprCommand [getLprCommand quiztemp.ps]
3888:
3889: if {$lprCommand == ""} {
3890: displayError "You must at least specify a print queue for lpr. \
3891: Nothing printed."
3892: return
3893: }
3894:
3895: if {$lprCommand == "Cancel"} {
3896: return
3897: }
3898:
3899: set type $gStudentSelection(type)
3900: set random $gStudentSelection(random)
3901:
3902: set gStudentSelection(type) Random
3903: set gStudentSelection(random) $gPrintSelection(random)
3904:
3905: if { [createDvi 0 1] == 2 } {
3906: displayMessage "Printing has been stopped"
3907: }
3908:
3909: printBody $lprCommand
3910:
3911: set gStudentSelection(type) $type
3912: set gStudentSelection(random) $random
3913:
3914: return 0
3915: }
3916:
3917: ###########################################################
3918: ###########################################################
3919: ###########################################################
3920: ###########################################################
3921: proc printSpecific {} {
3922: global gStudentSelection gPrintSelection
3923:
3924: set lprCommand [getLprCommand quiztemp.ps]
3925:
3926: if {$lprCommand == ""} {
3927: displayError "You must at least specify a print queue for lpr. \
3928: Nothing printed."
3929: return
3930: }
3931:
3932: if {$lprCommand == "Cancel"} {
3933: return
3934: }
3935:
3936: set type $gStudentSelection(type)
3937: set studentNumber $gStudentSelection(studentNumber)
3938:
3939: set gStudentSelection(type) Specific
3940: set gStudentSelection(studentNumber) $gPrintSelection(studentNumber)
3941:
3942: if { [createDvi 0 1 1] == 2 } {
3943: displayMessage "Printing has been stopped"
3944: }
3945:
3946: printBody $lprCommand
3947:
3948: set gStudentSelection(type) $type
3949: set gStudentSelection(studentNumber) $studentNumber
3950:
3951: return 0
3952: }
3953:
3954: ###########################################################
3955: ###########################################################
3956: ###########################################################
3957: ###########################################################
3958: proc printStudent { studentNumber } {
3959: global gStudentSelection gStopPrinting gDonePrinting
3960:
3961: set type $gStudentSelection(type)
3962: set studentNumberOld $gStudentSelection(studentNumber)
3963:
3964: set gStudentSelection(type) Specific
3965: set gStudentSelection(studentNumber) $studentNumber
3966:
3967: set createdDvi [createDvi 0 1]
3968:
3969: if { $createdDvi == 1 } { printBody } else {
3970: displayMessage "Printing has been stopped"
3971: set gStopPrinting 0
3972: set gDonePrinting 1
3973: }
3974:
3975: set gStudentSelection(type) $type
3976: set gStudentSelection(studentNumber) $studentNumberOld
3977:
3978: return 0
3979: }
3980:
3981: proc checkDestroyPrint { createDviWindow } {
3982: global gDonePrinting
3983: if { !$gDonePrinting } {
3984: if { [makeSure "Do you really wish to stop printing?"] == "Yes" } {
3985: global gStopPrinting
3986: set gStopPrinting 1
3987: after 1000 "destroyPrint $createDviWindow"
3988: }
3989: return
3990: }
3991: destroyPrint $createDviWindow
3992: }
3993:
3994: proc destroyPrint { createDviWindow } {
3995: trace vdelete gFile w updateCreateDvi
3996: destroy $createDviWindow
3997: removeWindowEntry CreateDvi
3998: }
3999:
4000: ###########################################################
4001: ###########################################################
4002: ###########################################################
4003: ###########################################################
4004: proc setupSetsToPrint { setVar startVar endVar {checkForHeader 1}} {
4005: global gPrintSelection gSetNumberText gLoadHeaderSet
4006: upvar $setVar set $startVar start $endVar end
4007: if { $gPrintSelection(sets) == "printRange" } {
4008: set start $gPrintSelection(setstart)
4009: set end $gPrintSelection(setend)
4010: set set "$start:$end"
4011: set errors ""
4012: for {set i $start} {$i <= $end} {incr i} {
4013: set gLoadHeaderSet $i
4014: if {[catch {getHeaderInfo}]} { append errors ", $i" }
4015: }
4016: if { $checkForHeader && $errors != "" } {
4017: set errors [string range $errors 1 end]
4018: if { [llength $errors] > 1 } {
4019: set errors "s$errors"
4020: set errors [linsert $errors [expr [llength $errors] - 1] and]
4021: }
4022: displayError "DB header has not yet been set for set$errors. Please set the DB Header before printing Sections."
4023: return 1
4024: }
4025: } else {
4026: set start [set end [set set $gSetNumberText]]
4027: set gLoadHeaderSet $gSetNumberText
4028: if {$checkForHeader && [catch {getHeaderInfo}]} {
4029: displayError "DB header has not yet been set. Please set the DB Header before printing Sections."
4030: return 1
4031: }
4032: }
4033: }
4034:
4035: ###########################################################
4036: ###########################################################
4037: ###########################################################
4038: ###########################################################
4039: proc printSection { { lprCommand "" } } {
4040: global gPrintSelection gCapaConfig gSetNumberText gWindowMenu \
4041: gCreateDviText gStopPrinting gPrefs gFile gDonePrinting \
4042: gLoadHeaderSet
4043:
4044: set gDonePrinting 0
4045: set showStopping 0
4046:
4047: if { [setupSetsToPrint set start end] == 1 } { return 1}
4048: if { $lprCommand == "" } {
4049: set showStopping 1
4050: set lprCommand [getLprCommand quiztemp.ps]
4051: if { $lprCommand == "" } {
4052: displayError "Print command was empty, unable to print."
4053: return 1
4054: }
4055: if {$lprCommand == "Cancel" } {
4056: return 1
4057: }
4058: }
4059:
4060: createCreateDviWin
4061:
4062: grab .createDvi
4063:
4064: $gCreateDviText delete 0.0 end
4065:
4066: switch $gPrefs(info) {
4067: Problem { set type "-T" }
4068: Answer { set type "-Ta" }
4069: ProblemAnswer { set type "-Tb" }
4070: default { set type "-T" }
4071: }
4072:
4073: if { [set gStopPrinting [expr 2 == [runLatex \
4074: "echo [pwd] | $gCapaConfig(qzparse_command) \
4075: -sec $gPrintSelection(section) -set $set \
4076: -d [pwd] -c [pwd] $type " gCreateDviText] ] ] } {
4077: for {set i $start} { $i <= $end} { incr i } {
4078: exec rm -f section$gPrintSelection(section)-set$i.tex
4079: }
4080: if {$showStopping} {
4081: displayMessage "Printing has been stopped."
4082: set gDonePrinting 1
4083: set gStopPrinting 0
4084: }
4085: return 1
4086: }
4087: if { $gStopPrinting } {
4088: displayMessage "Printing has been stopped."
4089: set gDonePrinting 1
4090: set gStopPrinting 0
4091: return 1
4092: }
4093:
4094: for { set i $start} { $i <= $end } { incr i } {
4095: if { ! [file exists section$gPrintSelection(section)-set$i.tex] } {
4096: if {$showStopping} {
4097: displayError "The qzparse command: $gCapaConfig(qzparse_command), was unable to produce the expected output. Printing stopped"
4098: set gStopPrinting 0
4099: set gDonePrinting 1
4100: }
4101: return 2
4102: }
4103:
4104: exec mv section$gPrintSelection(section)-set$i.tex quiztemp.tex
4105: exec /bin/rm -f quiztemp.dvi
4106:
4107: $gCreateDviText insert end "$gCapaConfig(latex_command)\n"
4108: $gCreateDviText see end
4109:
4110: if { [set gStopPrinting [ expr 2 == [runLatex \
4111: "pwd ; $gCapaConfig(latex_command) \
4112: quiztemp.tex < [file join / dev null ]" gCreateDviText ] ] ] } {
4113: if {$showStopping} {
4114: displayError "The LaTeX command: $gCapaConfig(latex_command), was unable to produce the expected output. Printing stopped"
4115: set gStopPrinting 0
4116: set gDonePrinting 1
4117: }
4118: return 1
4119: }
4120:
4121: if { $gStopPrinting } {
4122: displayMessage "Printing has been stopped."
4123: set gDonePrinting 1
4124: set gStopPrinting 0
4125: return 1
4126: }
4127:
4128: set a [expr ($showStopping) && ($end == $i)]
4129: if { [set gStopPrinting [printBody $lprCommand $a ] ] } {
4130: if {$showStopping} {
4131: displayMessage "Printing has been stopped."
4132: set gDonePrinting 1
4133: set gStopPrinting 0
4134: }
4135: return 1
4136: }
4137: if { $gStopPrinting } {
4138: displayMessage "Printing has been stopped."
4139: set gDonePrinting 1
4140: set gStopPrinting 0
4141: return 1
4142: }
4143: }
4144:
4145: set gDonePrinting 1
4146: return 0
4147: }
4148:
4149: ###########################################################
4150: ###########################################################
4151: ###########################################################
4152: ###########################################################
4153: proc printMultipleSections { } {
4154: global gPrintSelection gCapaConfig gSetNumberText gWindowMenu \
4155: gCreateDviText gStopPrinting gPrefs gDonePrinting
4156:
4157: #checks if the DB Header is set
4158: if { [setupSetsToPrint set start end] == 1 } { return 1}
4159:
4160: set sectionList [ getExistingSections ]
4161: set sectionsToPrint [ pickSections $sectionList "Select Sections to Print:" ]
4162:
4163: if { $sectionsToPrint == "" } {
4164: displayMessage "No sections selected, therefore nothing was printed."
4165: return 1
4166: }
4167: if { $sectionsToPrint == "Cancel" } {
4168: return 1
4169: }
4170:
4171: set lprCommand [getLprCommand quiztemp.ps]
4172: if { $lprCommand == "" } {
4173: displayError "Print command was empty, unable to print."
4174: return 1
4175: }
4176: if {$lprCommand == "Cancel" } {
4177: return 1
4178: }
4179:
4180: if { [makeSure "You have selected to print $gPrefs(info)s for sections: [string trim $sectionsToPrint], using the print command \"$lprCommand\", continue?"] == "Cancel" } {
4181: return 1
4182: }
4183:
4184: foreach section $sectionsToPrint {
4185: set gDonePrinting 0
4186: set gPrintSelection(section) $section
4187: if { [set gStopPrinting [printSection $lprCommand] ] } {
4188: set gDonePrinting 0
4189: if { $gStopPrinting == 2 } {
4190: displayError "The qzparse command: $gCapaConfig(qzparse_command), was unable to produce the expected output. Printing stopped"
4191: } else {
4192: displayMessage "Printing has been stopped."
4193: }
4194: set gDonePrinting 1
4195: return 1
4196: }
4197: if { $gStopPrinting } {
4198: displayMessage "Printing has been stopped."
4199: set gStopPrinting 0
4200: set gDonePrinting 1
4201: return 1
4202: }
4203: }
4204: set gDonePrinting 1
4205: displayMessage "Print jobs sent to the printer."
4206: return 0
4207: }
4208:
4209: ###########################################################
4210: ###########################################################
4211: ###########################################################
4212: ###########################################################
4213: proc printWholeClass { } {
4214: global gPrintSelection gCapaConfig gSetNumberText gWindowMenu \
4215: gCreateDviText gStopPrinting gPrefs gDonePrinting
4216:
4217: if {[catch {getHeaderInfo}]} {
4218: displayError "DB header has not yet been set, Please set DB Header before printing Sections."
4219: return 1
4220: }
4221: set sectionsToPrint [ getExistingSections ]
4222:
4223: if { $sectionsToPrint == "" } {
4224: displayMessage "No sections exist, therefore nothing was printed."
4225: return 1
4226: }
4227:
4228: set lprCommand [getLprCommand quiztemp.ps]
4229:
4230: if { $lprCommand == "" } {
4231: displayError "Print command was empty, unable to print."
4232: return 1
4233: }
4234: if {$lprCommand == "Cancel" } {
4235: return 1
4236: }
4237:
4238: if { [makeSure "You have selected to print $gPrefs(info)s for the entire class of [llength $sectionsToPrint] sections, using the print command $lprCommand, continue?"] == "Cancel" } {
4239: return 1
4240: }
4241:
4242: foreach section $sectionsToPrint {
4243: set section [lindex $section 0]
4244: set gPrintSelection(section) $section
4245: set gStopPrinting [printSection $lprCommand]
4246: if { $gStopPrinting } {
4247: if { $gStopPrinting == 2 } {
4248: displayError "$gCapaConfig(qzparse_command) was unable to produce the expected output. Printing stopped"
4249: } else {
4250: displayMessage "Printing has been stopped."
4251: }
4252: set gDonePrinting 1
4253: set gStopPrinting 0
4254: return 1
4255: }
4256: }
4257: set gDonePrinting 1
4258: displayMessage "Print jobs sent to the printer."
4259: return 0
4260: }
4261:
4262: ###########################################################
4263: # analyzeSet
4264: ###########################################################
4265: ###########################################################
4266: ###########################################################
4267: proc analyzeSet {} {
4268: global gChanged gWindowMenu gEditWindow gAnalyze gSetNumberText gNumberParsedText
4269:
4270: if { [catch {winfo exists $gEditWindow}] } { return }
4271: if { ![ winfo exists $gEditWindow ] } { return }
4272: if { $gChanged } { if { [askToSave 0 0] == "Cancel" } { return } }
4273: if { [winfo exists .analyzeSet] } {
4274: capaRaise .analyzeSet
4275: return
4276: }
4277:
4278: set analyze [toplevel .analyzeSet]
4279: $gWindowMenu add command -label "AnalyzeSet" \
4280: -command "capaRaise $analyze"
4281: wm title $analyze "Analyze Set"
4282:
4283: set settingsFrame [frame $analyze.settingsFrame]
4284: set dataFrame [frame $analyze.dataFrame]
4285: pack $settingsFrame $dataFrame -side top
4286:
4287: set classFrame [frame $settingsFrame.classFrame]
4288: set setFrame [frame $settingsFrame.setFrame]
4289: set probFrame [frame $settingsFrame.probFrame]
4290: set statusFrame [frame $settingsFrame.statusFrame]
4291: set statusBar [frame $settingsFrame.statusBar]
4292: set buttonFrame [frame $settingsFrame.buttonFrame]
4293: pack $classFrame $setFrame $probFrame $statusFrame $statusBar $buttonFrame \
4294: -side top
4295:
4296: set canvasFrame [frame $dataFrame.canvasFrame]
4297: set numberFrame [frame $dataFrame.numberFrame]
4298: pack $canvasFrame $numberFrame -side top
4299:
4300: set gAnalyze(class) [pwd]
4301: label $classFrame.label -textvariable gAnalyze(class)
4302: pack $classFrame.label
4303:
4304: set gAnalyze(set) $gSetNumberText
4305: label $setFrame.lbl -text "Set number:"
4306: label $setFrame.set -textvariable gAnalyze(set)
4307: # button $setFrame.change -text "Change" -command analyzeChangeSet
4308: pack $setFrame.lbl $setFrame.set -side left
4309:
4310: if { [set gAnalyze(maxprob) $gNumberParsedText] == "" } { set gAnalyze(maxprob) 1 }
4311:
4312: label $probFrame.label -text "Problem Number :"
4313: set gAnalyze(scale) [scale $probFrame.problem \
4314: -from 1 -to $gAnalyze(maxprob) \
4315: -variable gAnalyze(prob) -command analyzeUpdate \
4316: -orient h -length 150 -tickinterval 1]
4317: pack $probFrame.label $probFrame.problem -side left
4318:
4319: set gAnalyze(status) ""
4320: label $statusFrame.label -text "Status:"
4321: label $statusFrame.status -textvariable gAnalyze(status)
4322: pack $statusFrame.label $statusFrame.status -side left
4323:
4324: set gAnalyze(statcanvas) [canvas $statusBar.canvas -width 200 -height 20]
4325: pack $statusBar.canvas
4326: $gAnalyze(statcanvas) create rectangle 1 1 199 19 -outline black
4327: set gAnalyze(bar) [$gAnalyze(statcanvas) create rectangle 1 1 1 19 -fill red -outline black]
4328:
4329: button $buttonFrame.class -text "Run Class" -command "analyzeClass 1"
4330: button $buttonFrame.random -text "Run Random" -command analyzeRandom
4331: button $buttonFrame.stop -text "Stop" -command analyzeStop
4332: button $buttonFrame.close -text "Dismiss" -comman analyzeClose
4333: pack $buttonFrame.class $buttonFrame.random $buttonFrame.stop \
4334: $buttonFrame.close -side left
4335:
4336: set gAnalyze(canvaswidth) 600
4337: set gAnalyze(canvas) [canvas $canvasFrame.canvas -width $gAnalyze(canvaswidth) \
4338: -height 100]
4339: pack $gAnalyze(canvas)
4340:
4341: set hiFrame [frame $numberFrame.hiFrame]
4342: set lowFrame [frame $numberFrame.lowFrame]
4343: set uniqFrame [frame $numberFrame.uniqFrame]
4344: pack $lowFrame $hiFrame $uniqFrame -side left
4345: pack configure $hiFrame -anchor e
4346: pack configure $lowFrame -anchor w
4347:
4348: label $hiFrame.label -text "High End:"
4349: label $hiFrame.num -textvariable gAnalyze(highnum)
4350: pack $hiFrame.label $hiFrame.num -side left
4351:
4352: label $lowFrame.label -text "Low End:"
4353: label $lowFrame.num -textvariable gAnalyze(lownum)
4354: pack $lowFrame.label $lowFrame.num -side left
4355:
4356: label $uniqFrame.label -text "Num. Unique:"
4357: label $uniqFrame.num -textvariable gAnalyze(numuniq)
4358: pack $uniqFrame.label $uniqFrame.num -side left
4359:
4360: set gAnalyze(studentNumbers) [getStudentNumbers]
4361: set gAnalyze(exit) 0
4362: }
4363:
4364: ###########################################################
4365: # analyzeClass
4366: ###########################################################
4367: ###########################################################
4368: ###########################################################
4369: proc analyzeClass { {start 1} } {
4370: global gAnalyze gCapaConfig
4371: if { $gAnalyze(studentNumbers)=="" } { return }
4372: if { $start } {
4373: set gAnalyze(toprocess) $gAnalyze(studentNumbers)
4374: set gAnalyze(stop) 0
4375: set gAnalyze(update) 1
4376: set gAnalyze(done) 0
4377: set gAnalyze(total) [expr [llength $gAnalyze(toprocess)]/3]
4378: foreach name [array names gAnalyze *.\[alhu\]*] { unset gAnalyze($name) }
4379: }
4380: set number [lindex $gAnalyze(toprocess) 0]
4381: set name [lindex $gAnalyze(toprocess) 1]
4382: set section [lindex $gAnalyze(toprocess) 2]
4383: set gAnalyze(toprocess) [lrange $gAnalyze(toprocess) 3 end]
4384: set command "$gCapaConfig(answers_command) $number \"$name\" $section $gAnalyze(set)"
4385: set fileId [open "|$command" "r"]
4386: set gAnalyze(pid) [pid $fileId]
4387: fconfigure $fileId -blocking 0
4388: fileevent $fileId readable "analyzeLine $fileId"
4389: set gAnalyze(status) "Processing $number"
4390: incr gAnalyze(done)
4391: $gAnalyze(statcanvas) coords $gAnalyze(bar) 1 1 [expr 200*($gAnalyze(done)/double($gAnalyze(total)))] 19
4392: update idletasks
4393: }
4394:
4395: ###########################################################
4396: # analyzeEatQuestion
4397: ###########################################################
4398: ###########################################################
4399: ###########################################################
4400: proc analyzeEatQuestion { fileId } {
4401: global gAnalyze
4402: if { $gAnalyze(exit) } {
4403: fileevent $fileId readable ""
4404: catch {close $fileId}
4405: return
4406: }
4407: set aline [gets $fileId]
4408: if { $aline != "" } {
4409: switch -- [lindex [split $aline :] 0] {
4410: EQES { fileevent $fileId readable "analyzeLine $fileId" }
4411: }
4412: }
4413: if { [eof $fileId] } { analyzeEnd $fileId }
4414: }
4415:
4416: ###########################################################
4417: # analyzeLine
4418: ###########################################################
4419: ###########################################################
4420: ###########################################################
4421: proc analyzeLine { fileId } {
4422: global gAnalyze
4423:
4424: if { $gAnalyze(exit) } {
4425: fileevent $fileId readable ""
4426: catch {close $fileId}
4427: return
4428: }
4429: set aline [gets $fileId]
4430: if { $aline != "" } {
4431: switch [lindex [split $aline :] 0] {
4432: ANS {
4433: incr gAnalyze(problemNum)
4434: set ans [string range $aline 4 end]
4435: set length [llength $ans]
4436: lappend gAnalyze($gAnalyze(problemNum).ans) \
4437: [lindex $ans 0]
4438: if { ($length == 2) || ($length == 4)} {
4439: lappend gAnalyze($gAnalyze(problemNum).unit) \
4440: [lindex $ans end]
4441: }
4442: if { ($length == 3) || ($length == 4) } {
4443: lappend gAnalyze($gAnalyze(problemNum).low) \
4444: [lindex $ans 1]
4445: lappend gAnalyze($gAnalyze(problemNum).high) \
4446: [lindex $ans 2]
4447: }
4448: }
4449: SET { set gAnalyze(problemNum) 0 }
4450: DONE {
4451: set gAnalyze(maxprob) $gAnalyze(problemNum)
4452: $gAnalyze(scale) configure -to $gAnalyze(maxprob)
4453: }
4454: ERROR {
4455: fileevent $fileId readable ""
4456: displayError "Answers returned invalid message: $aline"
4457: fileevent $fileId readable "analyzeLine $fileId"
4458: }
4459: BQES { fileevent $fileId readable "analyzeEatQuestion $fileId" }
4460: default {
4461: }
4462: }
4463: }
4464: if { [eof $fileId] } { analyzeEnd $fileId }
4465: }
4466:
4467: ###########################################################
4468: # analyzeEnd
4469: ###########################################################
4470: ###########################################################
4471: ###########################################################
4472: proc analyzeEnd { fileId } {
4473: global gAnalyze
4474: if { [eof $fileId] } {
4475: fileevent $fileId readable ""
4476: catch {close $fileId}
4477: if { $gAnalyze(stop) } { return }
4478: if { [llength $gAnalyze(toprocess)] > 0 } {
4479: analyzeClass 0
4480: } else {
4481: analyzeUpdate
4482: set gAnalyze(status) "Done"
4483: }
4484: if { !$gAnalyze(update) } {
4485: incr gAnalyze(update)
4486: analyzeUpdate
4487: } else {
4488: incr gAnalyze(update)
4489: if { $gAnalyze(update) == 10 } {
4490: set gAnalyze(update) 0
4491: }
4492: }
4493: }
4494: }
4495:
4496: ###########################################################
4497: # analyzeRandom
4498: ###########################################################
4499: ###########################################################
4500: ###########################################################
4501: proc analyzeRandom { } {
4502: global gAnalyze
4503: set numToRun [getString . "How many random students should be run?"]
4504: if { $numToRun == "" } { return }
4505: if { [catch {incr numToRun} ] } {
4506: displayMessage "Invalid number."
4507: }
4508: incr numToRun -1
4509: set gAnalyze(total) $numToRun
4510: catch {unset gAnalyze(toprocess)}
4511: for { set i 0 } { $i < $numToRun } { incr i } {
4512: append gAnalyze(toprocess) "[format "%09d" $i] Random 999 "
4513: }
4514: set gAnalyze(stop) 0
4515: set gAnalyze(update) 1
4516: set gAnalyze(done) 0
4517: foreach name [array names gAnalyze *.\[alhu\]*] { unset gAnalyze($name) }
4518: analyzeClass 0
4519: }
4520:
4521: ###########################################################
4522: # analyzeStrings
4523: ###########################################################
4524: ###########################################################
4525: ###########################################################
4526: proc analyzeStrings { prob window create} {
4527: global gAnalyze
4528:
4529: if { ![winfo exists $window.analyzestrings] } { if {!$create} { return } }
4530: if { ![catch {set setWin [toplevel $window.analyzestrings]}] } {
4531: set msgFrame [frame $setWin.msgFrame]
4532: set valFrame [frame $setWin.valFrame]
4533: set buttonFrame [frame $setWin.buttonFrame]
4534: pack $msgFrame $valFrame $buttonFrame
4535: pack configure $valFrame -expand 1 -fill both
4536:
4537: message $msgFrame.msg -text "Correct Answers" -aspect 3000
4538: pack $msgFrame.msg
4539:
4540: set maxWidth 1
4541: foreach choice $gAnalyze($prob.ans) {
4542: if {[string length $choice]>$maxWidth} {set maxWidth [string length $choice]}
4543: }
4544: set maxStringWidth $maxWidth
4545: incr maxWidth 6
4546:
4547: set selectMode none
4548: listbox $valFrame.val -width [expr $maxWidth + 2] \
4549: -yscrollcommand "$valFrame.scroll set" -selectmode $selectMode
4550: scrollbar $valFrame.scroll -command "$valFrame.val yview"
4551: pack $valFrame.val $valFrame.scroll -side left
4552: pack configure $valFrame.val -expand 1 -fill both
4553: pack configure $valFrame.scroll -expand 0 -fill y
4554: button $buttonFrame.cancel -text "Dismiss" -command "destroy $setWin"
4555: pack $buttonFrame.cancel
4556: } else {
4557: set maxWidth 1
4558: set valFrame $window.analyzestrings.valFrame
4559: $valFrame.val delete 0 end
4560: foreach choice $gAnalyze($prob.ans) {
4561: if {[string length $choice]>$maxWidth} {set maxWidth [string length $choice]}
4562: }
4563: set maxStringWidth $maxWidth
4564: incr maxWidth 6
4565: }
4566: set lastchoice [lindex $gAnalyze($gAnalyze(prob).ans) 0]
4567: set num 1
4568: foreach choice [lsort $gAnalyze($gAnalyze(prob).ans)] {
4569: if { $lastchoice != $choice } {
4570: $valFrame.val insert end \
4571: "[format %-[set maxStringWidth]s $lastchoice] [format %5d $num]"
4572: set lastchoice $choice
4573: set num 1
4574: } else {
4575: incr num
4576: }
4577: }
4578: $valFrame.val insert end \
4579: "[format %-[set maxStringWidth]s $lastchoice] [format %5d $num]"
4580: }
4581:
4582: ###########################################################
4583: # analyzeUpdate
4584: ###########################################################
4585: ###########################################################
4586: ###########################################################
4587: proc analyzeUpdate { {newProbNumber 0} } {
4588: global gAnalyze
4589:
4590: if {[catch {set gAnalyze($gAnalyze(prob).ans)}]} { return }
4591: foreach problem [array names gAnalyze *.\[alh\]*] {
4592: if { [catch {set gAnalyze($problem) [lsort -real $gAnalyze($problem)]}]} {
4593: set gAnalyze($problem) [lsort $gAnalyze($problem)]
4594: }
4595: }
4596:
4597: set c $gAnalyze(canvas)
4598: $c delete all
4599: set gAnalyze(lownum) [set low [lindex $gAnalyze($gAnalyze(prob).ans) 0]]
4600: set gAnalyze(highnum) [set high [lindex $gAnalyze($gAnalyze(prob).ans) end]]
4601: set gAnalyze(numuniq) [llength [lunique $gAnalyze($gAnalyze(prob).ans)]]
4602: #don't draw anything if the answers aren't numbers
4603: if { [catch {expr $low + 1}]} {
4604: catch {destroy $c.button}
4605: update idletask
4606: button $c.button -text "List of strings" -command \
4607: "analyzeStrings $gAnalyze(prob) $c 1"
4608: $c create window [expr $gAnalyze(canvaswidth)/2.0] 40 -window $c.button
4609: analyzeStrings $gAnalyze(prob) $c 0
4610: return
4611: }
4612:
4613: $c create line 25 50 [expr $gAnalyze(canvaswidth) - 25] 50
4614: set diff [expr double($high-$low)]
4615: if { $diff == 0 } {
4616: set center [expr $gAnalyze(canvaswidth)/2.0]
4617: $c create rectangle [expr $center - 2] 48 [expr $center + 2] 52 -fill green
4618: update idletasks
4619: return
4620: }
4621: set delta [format "%1.e" [expr ($diff)/15.0]]
4622: set start [expr double(int($low/$delta)+1)*$delta]
4623: while { $start < $high } {
4624: set center [expr ($gAnalyze(canvaswidth)-50)*(($start-$low)/$diff)]
4625: set center [expr $center+25]
4626: $c create line $center 40 $center 60
4627: set start [expr $start + $delta]
4628: }
4629: if { ($low < 0) && ($high > 0) } {
4630: set center [expr ($gAnalyze(canvaswidth)-50)*((0-$low)/$diff)]
4631: set center [expr $center+25]
4632: $c create rectangle [expr $center - 1] 40 [expr $center + 1] 60
4633: }
4634: set lastpoint [lindex $gAnalyze($gAnalyze(prob).ans) 0]
4635: set num 0
4636: foreach point $gAnalyze($gAnalyze(prob).ans) {
4637: if { $lastpoint != $point } {
4638: set center [expr ($gAnalyze(canvaswidth)-50)*(($lastpoint-$low)/$diff)]
4639: set center [expr $center+25]
4640: $c create rectangle [expr $center - 2] [expr 48-$num] \
4641: [expr $center + 2] [expr 52+$num] -fill green
4642: set lastpoint $point
4643: set num 0
4644: } else {
4645: incr num
4646: }
4647: }
4648: set center [expr ($gAnalyze(canvaswidth)-50)*(($lastpoint-$low)/$diff)]
4649: set center [expr $center+25]
4650: $c create rectangle [expr $center - 2] [expr 48-$num] \
4651: [expr $center + 2] [expr 52+$num] -fill green
4652:
4653: update idletasks
4654: }
4655:
4656: ###########################################################
4657: # analyzeStop
4658: ###########################################################
4659: ###########################################################
4660: ###########################################################
4661: proc analyzeStop {} {
4662: global gAnalyze
4663: set gAnalyze(stop) 1
4664: set gAnalyze(status) "Stopped"
4665: exec kill -SIGKILL $gAnalyze(pid)
4666: }
4667:
4668: ###########################################################
4669: # analyzeClose
4670: ###########################################################
4671: ###########################################################
4672: ###########################################################
4673: proc analyzeClose { } {
4674: global gAnalyze
4675: destroy [winfo toplevel $gAnalyze(canvas)]
4676: unset gAnalyze
4677: global gAnalyze
4678: set gAnalyze(exit) 1
4679: }
4680:
4681: ###########################################################
4682: # checkIfValidFilename
4683: ###########################################################
4684: ###########################################################
4685: ###########################################################
4686: proc checkIfValidFilename {} {
4687: global gSetNumberText gPreviewButton
4688: if { [regexp \[^0-9\]+ $gSetNumberText] } {
4689: displayError "This file is not properly named. \n\nA main assignment file must be named setX.qz, where X is replaced by a number between 1 and 99 inclusive. \n\nPlease do a \"Save .qz As\". \n\nUntil the file is properly named you will not be able to Preview, Create .dvi, or Print."
4690: $gPreviewButton configure -state disabled
4691: .main entryconfigure 5 -state disabled
4692: .main entryconfigure 7 -state disabled
4693: return 0
4694: }
4695: $gPreviewButton configure -state normal
4696: .main entryconfigure 5 -state normal
4697: .main entryconfigure 7 -state normal
4698: return 1
4699: }
4700:
4701: ###########################################################
4702: # updateChangeStatus
4703: ###########################################################
4704: ###########################################################
4705: ###########################################################
4706: proc updateChangeStatus { name1 name2 op } {
4707: global gChanged gRefChanged gRefText gChangedLast gRefChangedLast \
4708: gEditWindow gWindowMenu gRefFile
4709: if { $name1 == "gChanged" } {
4710: if { $gChanged != $gChangedLast } {
4711: set gChangedLast $gChanged
4712: global gFile
4713: if { [catch {set gEditWindow}] } { return }
4714: if { ![winfo exists $gEditWindow] } { return }
4715: if { $gChanged } {
4716: catch {removeWindowEntry "$gFile*"}
4717: wm title [winfo toplevel $gEditWindow] "$gFile (Modified)"
4718: $gWindowMenu add command -label "$gFile (Modified)" -command \
4719: "capaRaise $gEditWindow"
4720: } else {
4721: catch {removeWindowEntry "$gFile*"}
4722: wm title [winfo toplevel $gEditWindow] "$gFile"
4723: $gWindowMenu add command -label "$gFile" -command \
4724: "capaRaise $gEditWindow"
4725: }
4726: }
4727: } else {
4728: if { $gRefChanged($name2) != $gRefChangedLast($name2) } {
4729: if { [catch {set gRefText($name2)}] } { return }
4730: if { ![winfo exists $gRefText($name2)] } { return }
4731: if { $gRefChanged($name2) } {
4732: catch {removeWindowEntry "Reference $gRefFile($name2)*" }
4733: wm title [winfo toplevel $gRefText($name2)] "$gRefFile($name2) (Modified)"
4734: $gWindowMenu add command -label "Reference $gRefFile($name2) (Modified)" \
4735: -command "capaRaise [winfo toplevel $gRefText($name2)]"
4736: } else {
4737: catch {removeWindowEntry "Reference $gRefFile($name2)*" }
4738: wm title [winfo toplevel $gRefText($name2)] "$gRefFile($name2)"
4739: $gWindowMenu add command -label "Reference $gRefFile($name2)" \
4740: -command "capaRaise [winfo toplevel $gRefText($name2)]"
4741: }
4742: }
4743: }
4744: }
4745: ###########################################################
4746: # main
4747: ###########################################################
4748: # sets up the auto_path variable, some globals and adds some
4749: # options then calls createControlWindow to give the user something
4750: # to do
4751: ###########################################################
4752: # Arguments: None
4753: # Returns: Nothing
4754: # Globals:
4755: ###########################################################
4756:
4757: source quizzer.templates.tcl
4758:
4759: if { [lindex $auto_path 0] == "./lib/tcl7.5" } {
4760: set auto_path ""
4761: lappend auto_path [pwd]/lib/tcl7.5
4762: lappend auto_path [pwd]/lib/tk4.1
4763: }
4764:
4765: lappend auto_path /usr/local/lib/CAPA45/Quizzer
4766: lappend auto_path [pwd]
4767:
4768: set font 8x13bold
4769: catch {
4770: if { $argc > 0 } {
4771: switch -glob -- [lindex $argv 0] {
4772: {-[Ll]*} { set font 9x15bold }
4773: {-[Mm]*} -
4774: {-[Nn]*} { set font 8x13bold }
4775: {-[Ss]*} { set font fixed }
4776: }
4777: }
4778: }
4779: option add *font $font
4780: createControlWindow
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>