# $Id: gsascmds.tcl 119 2009-12-04 23:00:43Z toby $ # platform-specific code if {$tcl_platform(platform) == "windows"} { if [catch {package require winexec}] { tk_dialog .err "WINEXEC Error" \ "Error -- Unable to load the WINEXEC package. This is needed in Win95 machines" \ error 0 Quit destroy . } if {$tcl_platform(os) == "Windows 95" || $tcl_platform(os) == "Windows 98" } { # this creates a DOS box to run a program in proc forknewterm {title command "background 0" "scrollbar 1" "wait 1"} { global env expgui # Windows environment variables # -95 does not seem to be able to use these set env(GSAS) [file nativename $expgui(gsasdir)] # PGPLOT_FONT is needed by PGPLOT set env(PGPLOT_FONT) [file nativename [file join $expgui(gsasdir) fonts grfont.dat]] # this is the number of lines/page in the .LST (etc.) file set env(LENPAGE) 60 set pwd [file nativename [pwd]] # check the path -- can DOS use it? if {[string first // [pwd]] != -1} { tk_dialog .braindead "Invalid Path" \ {Error -- Use "Map network drive" to access this directory with a letter (e.g. F:) \ Win-95 can't directly access a network drive in DOS} error 0 OK return } # all winexec commands are background commands # if $background # pause is hard coded in the .BAT file #if $wait { # append command " pause" #} # replace the forward slashes with backward regsub -all / $command \\ command # Win95 does not seem to inherit the environment from Tcl env vars # so define it in the .BAT file winexec -d [file nativename [pwd]] \ [file join $expgui(scriptdir) gsastcl.bat] \ "[file nativename $expgui(gsasdir)] $command" } } else { # now for - brain-dead Windows-NT # this creates a DOS box to run a program in proc forknewterm {title command "background 0" "scrollbar 1" "wait 1"} { global env expgui # Windows environment variables set env(GSAS) [file nativename $expgui(gsasdir)] # PGPLOT_FONT is needed by PGPLOT set env(PGPLOT_FONT) [file nativename [file join $expgui(gsasdir) fonts grfont.dat]] # this is the number of lines/page in the .LST (etc.) file set env(LENPAGE) 60 # all winexec commands are background commands -- ignore background arg # can't get pause to work! -- ignore wait set prevcmd {} foreach cmd $command { if {$prevcmd != ""} { tk_dialog .done_yet Confirm "Press OK to start command $cmd" "" 0 OK } # replace the forward slashes with backward regsub -all / $cmd \\ cmd # cmd.exe must be in the path -- lets hope that at least works! winexec -d [file nativename [pwd]] cmd.exe "/c $cmd" set prevcmd $cmd } } } } else { if [catch {set env(GSASBACKSPACE)}] {set env(GSASBACKSPACE) 1} # this creates a xterm window to run a program in proc forknewterm {title command "background 0" "scrollbar 1" "wait 1"} { global env expgui # UNIX environment variables set env(GSASEXE) $expgui(gsasexe) set env(ATOMDATA) [file join $expgui(gsasdir) data atmdata.dat] set env(ATMXSECT) [file join $expgui(gsasdir) data atmxsect.dat] # PGPLOT_DIR is needed by PGPLOT set env(PGPLOT_DIR) [file join $expgui(gsasdir) pgl] # this is the number of lines/page in the .LST (etc.) file set env(LENPAGE) 60 set termopts {} if $env(GSASBACKSPACE) { append termopts \ {-xrm "xterm*VT100.Translations: #override\\n BackSpace: string(\\177)"} } if $scrollbar { append termopts " -sb" } else { append termopts " +sb" } if $background { set suffix {&} } else { set suffix {} } # if $wait { append command "\; echo -n Press Enter to continue \; read x" } if !$background {wm iconify .} catch {eval exec xterm $termopts -title [list $title] \ -e /bin/sh -c [list $command] $suffix} errmsg if $expgui(debug) {puts "xterm result = $errmsg"} if !$background {wm deiconify .} } } # get a value in a modal toplevel proc getstring {what "chars 40" "quit 1" "initvalue {}"} { global expgui expmap set w .global catch {destroy $w} toplevel $w -bg beige wm title $w "Input $what" set expgui(temp) {} pack [frame $w.0 -bd 6 -relief groove -bg beige] \ -side top -expand yes -fill both grid [label $w.0.a -text "Input a value for the $what" \ -bg beige] \ -row 0 -column 0 -columnspan 10 grid [entry $w.0.b -textvariable expgui(temp) -width $chars] \ -row 1 -column 0 set expgui(temp) $initvalue pack [frame $w.b] -side top pack [button $w.b.2 -text Set -command "destroy $w"] -side left if $quit { pack [button $w.b.3 -text Quit \ -command "set expgui(temp) {}; destroy $w"] -side left } bind $w "destroy $w" # force the window to stay on top putontop $w focus $w.b.2 tkwait window $w afterputontop return $expgui(temp) } # run a GSAS program that does not require an experiment file proc runGSASprog {proglist} { global expgui tcl_platform set cmd {} foreach prog $proglist { if {$tcl_platform(platform) == "windows"} { append cmd " \"$expgui(gsasexe)/${prog}.exe \" " } else { if {$cmd != ""} {append cmd "\;"} append cmd "[file join $expgui(gsasexe) $prog]" } } forknewterm $prog $cmd 0 1 1 } # run a GSAS program that requires an experiment file for input/output proc runGSASwEXP {proglist} { global expgui tcl_platform # Save the current exp file savearchiveexp # load the changed .EXP file automatically? if {$expgui(autoexpload)} { # disable the file changed monitor set expgui(expModifiedLast) 0 } set cmd {} set expnam [file root [file tail $expgui(expfile)]] foreach prog $proglist { if {$prog == "expedt" && $expgui(archive)} archiveexp if {$tcl_platform(platform) == "windows"} { append cmd " \"$expgui(gsasexe)/${prog}.exe $expnam \" " } else { if {$cmd != ""} {append cmd "\;"} append cmd "[file join $expgui(gsasexe) $prog] $expnam" } } forknewterm "$prog -- $expnam" $cmd 0 1 1 # load the changed .EXP file automatically? if {$expgui(autoexpload)} { # load the revised exp file loadexp $expgui(expfile) } # wm deiconify . } # run liveplot proc liveplot {} { global expgui liveplot wishshell set expnam [file root [file tail $expgui(expfile)]] exec $wishshell [file join $expgui(scriptdir) liveplot] \ $expnam $liveplot(hst) $liveplot(legend) & } # run lstview proc lstview {} { global expgui wishshell set expnam [file root [file tail $expgui(expfile)]] exec $wishshell [file join $expgui(scriptdir) lstview] $expnam & } # run widplt proc widplt {} { global expgui wishshell exec $wishshell [file join $expgui(scriptdir) widplt] \ $expgui(expfile) & } # show help information proc showhelp {} { global expgui_helplist helpmsg set helpmsg {} set frm .help catch {destroy $frm} toplevel $frm wm title $frm "Command Help" pack [message $frm.0 -text \ "Click on an entry below to see help on a GSAS command" ] \ -side top pack [frame $frm.a -width 20 -height 15] \ -side top -expand yes -fill both pack [message $frm.help -textvariable helpmsg -relief groove] \ -side left -fill both -expand yes set lst [array names expgui_helplist] listbox $frm.a.cmds -relief raised -bd 2 -yscrollcommand \ "$frm.a.scroll set" -height 15 -width 0 scrollbar $frm.a.scroll -command "$frm.a.cmds yview" foreach item [lsort $lst] { $frm.a.cmds insert end $item } if {[$frm.a.cmds curselection] == ""} {$frm.a.cmds selection set 0} button $frm.a.done -text Done -command "destroy $frm" bind $frm.a.cmds \ "+set helpmsg \$expgui_helplist(\[$frm.a.cmds get \[$frm.a.cmds curselection\]\])" pack $frm.a.scroll -side left -fill y pack $frm.a.cmds -side left -expand yes -anchor w pack $frm.a.done -side right -expand no # get the size of the window and expand the message boxes to match update set width [lindex [split [wm geometry $frm] x+] 0] $frm.0 config -width $width $frm.help config -width $width # waitdone $frm } # compute the composition for each phase and display in a toplevel proc composition {} { global expmap expgui set Z 1 foreach phase $expmap(phaselist) { catch {unset total} foreach atom $expmap(atomlist_$phase) { set type [atominfo $phase $atom type] set mult [atominfo $phase $atom mult] if [catch {set total($type)}] { set total($type) [expr \ $mult * [atominfo $phase $atom frac]] } else { set total($type) [expr $total($type) + \ $mult * [atominfo $phase $atom frac]] } if {$mult > $Z} {set Z $mult} } append text "\nPhase $phase\n" append text " Unit cell contents\n" foreach type [lsort [array names total]] { append text " $type[format %8.3f $total($type)]" } append text "\n\n" append text " Asymmetric Unit contents (Z=$Z)\n" foreach type [lsort [array names total]] { append text " $type[format %8.3f [expr $total($type)/$Z]]" } append text "\n" } catch {destroy .comp} toplevel .comp wm title .comp Composition pack [label .comp.results -text $text \ -font $expgui(coordfont) -justify left] -side top pack [frame .comp.box] -side top pack [button .comp.box.1 -text Close -command "destroy .comp"] -side left set lstnam [string toupper [file tail [file rootname $expgui(expfile)].LST]] pack [button .comp.box.2 -text "Save to $lstnam file" \ -command "writelst [list $text] ; destroy .comp"] -side left } # write text to the .LST file proc writelst {text} { global expgui set lstnam [file rootname $expgui(expfile)].LST set fp [open $lstnam a] puts $fp "\n-----------------------------------------------------------------" puts $fp $text puts $fp "-----------------------------------------------------------------\n" close $fp } # save coordinates in an MSI .xtl file proc exp2xtl {} { global expmap expgui catch {destroy .export} toplevel .export wm title .export "Export coordinates" pack [label .export.lbl -text "Export coordinates in MSI .xtl format"\ ] -side top -anchor center pack [frame .export.ps] -side top -anchor w pack [label .export.ps.lbl -text "Select phase: "] -side left foreach num $expmap(phaselist) { pack [button .export.ps.$num -text $num \ -command "SetExportPhase $num"] -side left } pack [frame .export.sg] -side top pack [label .export.sg.1 -text "Space Group: "] -side left pack [entry .export.sg.2 -textvariable expgui(export_sg) -width 8] -side left pack [checkbutton .export.sg.3 -variable expgui(export_orig) -text "Origin 2"] -side left pack [frame .export.but] -side top if {[llength $expmap(phaselist)] > 0} { pack [button .export.but.1 -text Write -command writextl] -side left SetExportPhase [lindex $expmap(phaselist) 0] } pack [button .export.but.2 -text Quit -command "destroy .export"] -side left } proc SetExportPhase {phase} { global expmap expgui foreach n $expmap(phaselist) { if {$n == $phase} { .export.ps.$n config -relief sunken } else { .export.ps.$n config -relief raised } } set expgui(export_phase) $phase # remove spaces from space group set spacegroup [phaseinfo $phase spacegroup] if {[string toupper [string range $spacegroup end end]] == "R"} { set spacegroup [string range $spacegroup 0 \ [expr [string length $spacegroup]-2]] } regsub -all " " $spacegroup "" expgui(export_sg) } proc writextl {} { global expgui expmap if ![catch { set phase $expgui(export_phase) set origin $expgui(export_orig) set spsymbol $expgui(export_sg) } errmsg] { set errmsg {} if {$phase == ""} { set errmsg "Error: invalid phase number $phase" } elseif {$spsymbol == ""} { set errmsg "Error: invalid Space Group: $spsymbol" } } if {$errmsg != ""} { tk_dialog .errorMsg "Export error" $errmsg warning 0 "OK" return } if [catch { set filnam [file rootname $expgui(expfile)]_${phase}.xtl set spacegroup [phaseinfo $phase spacegroup] set fp [open $filnam w] puts $fp "TITLE from $expgui(expfile)" puts $fp "TITLE history [string trim [lindex [exphistory last] 1]]" puts $fp "TITLE phase [phaseinfo $phase name]" puts $fp "CELL" puts $fp " [phaseinfo $phase a] [phaseinfo $phase b] [phaseinfo $phase c] [phaseinfo $phase alpha] [phaseinfo $phase beta] [phaseinfo $phase gamma]" puts $fp "Symmetry Label $spsymbol" set rhomb 0 if {[string toupper [string range $spacegroup end end]] == "R"} { set rhomb 1 } if $origin { puts $fp "Symmetry Qualifier origin_2" } if $rhomb { puts $fp "Symmetry Qualifier rhombohedral" } # are there anisotropic atoms? set aniso 0 foreach atom $expmap(atomlist_$phase) { if {[atominfo $phase $atom temptype] == "A"} {set aniso 1} } puts $fp "ATOMS" if $aniso { puts $fp "NAME X Y Z OCCUP U11 U22 U33 U12 U13 U23" foreach atom $expmap(atomlist_$phase) { set label [atominfo $phase $atom label] # remove () characters if {[atominfo $phase $atom temptype] == "A"} { puts $fp "$label [atominfo $phase $atom x] \ [atominfo $phase $atom y] [atominfo $phase $atom z] \ [atominfo $phase $atom frac] \ [atominfo $phase $atom U11] \ [atominfo $phase $atom U22] \ [atominfo $phase $atom U33] \ [atominfo $phase $atom U12] \ [atominfo $phase $atom U13] \ [atominfo $phase $atom U23]" } else { puts $fp "$label [atominfo $phase $atom x] \ [atominfo $phase $atom y] [atominfo $phase $atom z] \ [atominfo $phase $atom frac] \ [atominfo $phase $atom Uiso] \ [atominfo $phase $atom Uiso] \ [atominfo $phase $atom Uiso] \ 0 0 0 " } } } else { puts $fp "NAME X Y Z UISO OCCUP" foreach atom $expmap(atomlist_$phase) { set label [atominfo $phase $atom label] # remove () characters regsub -all "\[()\]" $label "" label puts $fp "$label [atominfo $phase $atom x] \ [atominfo $phase $atom y] [atominfo $phase $atom z] \ [atominfo $phase $atom Uiso] [atominfo $phase $atom frac]" } } } errmsg] { catch {close $fp} tk_dialog .errorMsg "Export error" $errmsg warning 0 "OK" } else { catch {close $fp} tk_dialog .ok "Done" \ "File [file tail $filnam] written in directory [file dirname $filnam]" \ warning 0 "OK" } if {[llength $expmap(phaselist)] == 1} {destroy .export} } # convert a file proc convfile {} { global tcl_platform if {$tcl_platform(platform) == "windows"} { convwin } else { convunix } } # file conversions for UNIX (convstod convdtos) proc convunix {} { global expgui infile outfile set frm .file catch {destroy $frm} toplevel $frm wm title $frm "Convert File" pack [frame [set frm0 $frm.0] -bd 2 -relief groove] \ -padx 3 -pady 3 -side top -fill x pack [frame $frm.mid] -side top pack [frame [set frmA $frm.mid.1] -bd 2 -relief groove] \ -padx 3 -pady 3 -side left pack [label $frmA.0 -text "Select an input file"] -side top -anchor center pack [frame [set frmB $frm.mid.2] -bd 2 -relief groove] \ -padx 3 -pady 3 -side left pack [label $frmB.0 -text "Enter an output file"] -side top -anchor center pack [frame [set frmC $frm.3] ] -padx 3 -pady 3 -side top pack [label $frm0.1 -text "Convert to:"] -side top -anchor center pack [frame $frm0.2] -side top -anchor center pack [radiobutton $frm0.2.d -text "direct access" -value convstod \ -command setoutfile \ -variable outfile(type)] -side left -anchor center pack [radiobutton $frm0.2.s -text "sequential" -value convdtos \ -command setoutfile \ -variable outfile(type)] -side right -anchor center set outfile(type) "" pack [button $frmC.b -text Convert -command "valid_conv_unix"] -side left pack [button $frmC.q -text Quit -command "set infile(done) 1"] -side left unixcnvbox $frmA infile 1 unixcnvbox $frmB outfile 0 set infile(done) 0 bind $frm "valid_conv_unix" # force the window to stay on top putontop $frm focus $frmC.q update tkwait variable infile(done) destroy $frm afterputontop } # validate the files and make the conversion -- unix proc valid_conv_unix {} { global infile outfile expgui set error {} if {$outfile(type) == "convstod" || $outfile(type) == "convdtos"} { set convtype $outfile(type) } else { append error "You must specify a conversion method: to direct access or to sequential.\n" } if {$infile(name) == ""} { append error "You must specify an input file to convert.\n" } if {$outfile(name) == ""} { append error "You must specify an output file name for the converted file.\n" } if {$error != ""} { tk_dialog .warn Notify $error warning 0 OK return } if {$infile(name) == $outfile(name)} { tk_dialog .warn Notify "Sorry, filenames must differ" warning 0 OK return } if ![file exists [file join $infile(dir) $infile(name)]] { tk_dialog .warn Notify \ "Sorry, file $infile(name) not found in $infile(dir)" warning 0 OK return } if [file exists [file join $outfile(dir) $outfile(name)]] { if [tk_dialog .warn Notify \ "Warning: file $outfile(name) exists in $outfile(dir). OK to overwrite?" \ warning 0 OK No] return } if [catch { exec [file join $expgui(gsasexe) $convtype] < \ [file join $infile(dir) $infile(name)] > \ [file join $outfile(dir) $outfile(name)] } errmsg] { tk_dialog .warn Notify "Error in conversion:\n$errmsg" warning 0 OK } else { if [tk_dialog .converted Notify \ "File converted. Convert more files?" \ "" 0 Yes No] {set infile(done) 1} } } # create a file box for UNIX conversions proc unixcnvbox {bx filvar diropt} { global ${filvar} expgui pack [frame $bx.top] -side top pack [label $bx.top.a -text "Directory" ] -side left set ${filvar}(FileDirButtonMenu) [tk_optionMenu $bx.top.d ${filvar}(dir) [pwd] ] pack $bx.top.d -side left set ${filvar}(dir) [pwd] # pack [label $bx.d -textvariable ${filvar}(dir) -bd 2 -relief raised ] -side top # set ${filvar}(dir) [pwd] pack [frame $bx.a -width 200 -height 75] -side top -expand yes -fill both listbox $bx.a.files -relief raised -bd 2 -yscrollcommand "$bx.a.scroll set" \ -height 15 -width 0 scrollbar $bx.a.scroll -command "$bx.a.files yview" unixFilChoose $bx $bx.a.files $filvar $diropt if {$filvar == "infile"} { bind $bx.a.files \ "unixFilChoose $bx $bx.a.files $filvar $diropt; setoutfile" } else { bind $bx.a.files \ "unixFilChoose $bx $bx.a.files $filvar $diropt" } pack $bx.a.scroll -side left -fill y pack $bx.a.files -side left -fill both -expand yes pack [entry $bx.c -textvariable ${filvar}(name)] -side top } # select a file or directory, also called when box is created to fill it proc unixFilChoose {frm box filvar {dironly 1}} { global $filvar set select [$box curselection] if {$select == ""} { set file . } else { set file [string trim [$box get $select]] } if [file isdirectory [file join [set ${filvar}(dir)] $file]] { if {$file == ".."} { set ${filvar}(dir) [file dirname [set ${filvar}(dir)] ] } elseif {$file != "."} { set ${filvar}(dir) [file join [set ${filvar}(dir)] $file] } [set ${filvar}(FileDirButtonMenu)] delete 0 end set list "" set dir "" foreach subdir [file split [set ${filvar}(dir)]] { set dir [file join $dir $subdir] lappend list $dir } foreach path $list { [set ${filvar}(FileDirButtonMenu)] add command -label $path \ -command "[list set ${filvar}(dir) $path]; \ unixFilChoose $frm $box $filvar $dironly" } set ${filvar}(name) {} $box delete 0 end $box insert end {.. } foreach file [lsort [glob -nocomplain \ [file join [set ${filvar}(dir)] *] ] ] { if {[file isdirectory $file]} { # is this / needed here? Does it cause a problem in MacGSAS? $box insert end [file tail $file]/ } elseif {$dironly == 1} { $box insert end [file tail $file] } elseif {$dironly == 2 && [file extension $file] == ".EXP"} { $box insert end [file tail $file] } } return } set ${filvar}(name) [file tail $file] } # set new file name from old -- used for convunix proc setoutfile {} { global infile outfile if {$outfile(type) == "convstod"} { set lfile [string toupper $infile(name)] } elseif {$outfile(type) == "convdtos"} { set lfile [string tolower $infile(name)] } else { set lfile "" } if {$infile(name) == $lfile} { set outfile(name) {} } else { set outfile(name) $lfile } } #------------------------------------------------------------------------------ # file conversions for Windows #------------------------------------------------------------------------------ proc convwin {} { global expgui set frm .file catch {destroy $frm} toplevel $frm wm title $frm "Convert File" pack [frame [set frmA $frm.1] -bd 2 -relief groove] -padx 3 -pady 3 -side left pack [frame [set frmC $frm.3] ] -padx 3 -pady 3 -side left pack [button $frmC.b -text Convert -command "ValidWinCnv $frm"] \ -side top pack [button $frmC.q -text Quit -command "destroy $frm"] -side top pack [label $frmA.0 -text "Select a file to convert"] -side top -anchor center winfilebox $frm bind $frm "ValidWinCnv $frm" # force the window to stay on top putontop $frm focus $frmC.q tkwait window $frm afterputontop } # validate the files and make the conversion proc ValidWinCnv {frm} { global expgui # change backslashes to something sensible regsub -all {\\} $expgui(FileMenuCnvName) / expgui(FileMenuCnvName) # allow entry of D: for D:/ and D:TEST for d:/TEST if {[string first : $expgui(FileMenuCnvName)] != -1 && \ [string first :/ $expgui(FileMenuCnvName)] == -1} { regsub : $expgui(FileMenuCnvName) :/ expgui(FileMenuCnvName) } if {$expgui(FileMenuCnvName) == ""} { set expgui(FileMenuDir) [file dirname [set expgui(FileMenuDir)] ] ChooseWinCnv $frm return } elseif [file isdirectory \ [file join $expgui(FileMenuDir) $expgui(FileMenuCnvName)]] { if {$expgui(FileMenuCnvName) != "."} { set expgui(FileMenuDir) \ [file join $expgui(FileMenuDir) $expgui(FileMenuCnvName)] } ChooseWinCnv $frm return } set file [file join $expgui(FileMenuDir) $expgui(FileMenuCnvName)] if ![file exists $file] { tk_dialog .warn "Convert Error" \ "File $file does not exist" question 0 "OK" return } set tmpname "[file join [file dirname $file] tempfile.xxx]" set oldname "[file rootname $file].org" if [file exists $oldname] { set ans [tk_dialog .warn "OK to overwrite?" \ "File [file tail $oldname] exists in [file dirname $oldname]. OK to overwrite?" question 0 \ "Yes" "No"] if $ans return catch {file delete $oldname} } if [catch { set in [open $file r] set out [open $tmpname w] set len [gets $in line] if {$len > 160} { # this is a UNIX file. Hope there are no control characters set i 0 set j 79 while {$j < $len} { puts $out [string range $line $i $j] incr i 80 incr j 80 } } else { while {$len >= 0} { append line " " append line " " set line [string range $line 0 79] puts $out $line set len [gets $in line] } } close $in close $out file rename $file $oldname file rename $tmpname $file } errmsg] { tk_dialog .warn Notify "Error in conversion:\n$errmsg" warning 0 OK } else { if [tk_dialog .converted Notify \ "File [file tail $file] converted. (Original saved as [file tail $oldname]).\n\n Convert more files?" \ "" 0 Yes No] {destroy $frm} } } # create a file box proc winfilebox {frm} { global expgui set bx $frm.1 pack [frame $bx.top] -side top pack [label $bx.top.a -text "Directory" ] -side left set expgui(FileDirButtonMenu) [tk_optionMenu $bx.top.d expgui(FileMenuDir) [pwd] ] pack $bx.top.d -side left set expgui(FileMenuDir) [pwd] # the icon below is from tk8.0/tkfbox.tcl set upfolder [image create bitmap -data { #define updir_width 28 #define updir_height 16 static char updir_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x01, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0x07, 0x00, 0x01, 0x90, 0x0f, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0xfe, 0x07, 0x01, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0xf0, 0xff, 0xff, 0x01};}] pack [button $bx.top.b -image $upfolder \ -command "updir; ChooseWinCnv $frm" ] pack [frame $bx.a -width 200 -height 75] -side top -expand yes -fill both listbox $bx.a.files -relief raised -bd 2 \ -yscrollcommand "sync2boxes $bx.a.files $bx.a.dates $bx.a.scroll" \ -height 15 -width 0 listbox $bx.a.dates -relief raised -bd 2 \ -yscrollcommand "sync2boxes $bx.a.dates $bx.a.files $bx.a.scroll" \ -height 15 -width 0 -takefocus 0 scrollbar $bx.a.scroll -command "move2boxesY \" $bx.a.files $bx.a.dates \" " ChooseWinCnv $frm bind $bx.a.files "ReleaseWinCnv $frm" bind $bx.a.dates "ReleaseWinCnv $frm" bind $bx.a.files "SelectWinCnv $frm" bind $bx.a.dates "SelectWinCnv $frm" pack $bx.a.scroll -side left -fill y pack $bx.a.files $bx.a.dates -side left -fill both -expand yes pack [entry $bx.c -textvariable expgui(FileMenuCnvName)] -side top } # set the box or file in the selection window proc ReleaseWinCnv {frm} { global expgui set files $frm.1.a.files set dates $frm.1.a.dates set select [$files curselection] if {$select == ""} { set select [$dates curselection] } if {$select == ""} { set expgui(FileMenuCnvName) "" } else { set expgui(FileMenuCnvName) [string trim [$files get $select]] } if {$expgui(FileMenuCnvName) == ""} { set expgui(FileMenuDir) [file dirname $expgui(FileMenuDir)] ChooseWinCnv $frm } elseif [file isdirectory \ [file join [set expgui(FileMenuDir)] $expgui(FileMenuCnvName)]] { if {$expgui(FileMenuCnvName) != "."} { set expgui(FileMenuDir) [file join $expgui(FileMenuDir) $expgui(FileMenuCnvName)] ChooseWinCnv $frm } } return } # select a file or directory -- called on double click proc SelectWinCnv {frm} { global expgui set files $frm.1.a.files set dates $frm.1.a.dates set select [$files curselection] if {$select == ""} { set select [$dates curselection] } if {$select == ""} { set file . } else { set file [string trim [$files get $select]] } if {$file == ""} { set expgui(FileMenuDir) [file dirname [set expgui(FileMenuDir)] ] ChooseWinCnv $frm } elseif [file isdirectory [file join [set expgui(FileMenuDir)] $file]] { if {$file != "."} { set expgui(FileMenuDir) [file join [set expgui(FileMenuDir)] $file] ChooseWinCnv $frm } } else { set expgui(FileMenuCnvName) [file tail $file] ValidWinCnv $frm } } # fill the files & dates & Directory selection box with current directory, # also called when box is created to fill it proc ChooseWinCnv {frm} { global expgui set files $frm.1.a.files set dates $frm.1.a.dates set expgui(FileMenuCnvName) {} $files delete 0 end $dates delete 0 end $files insert end {} $dates insert end {(Directory)} set filelist [glob -nocomplain \ [file join [set expgui(FileMenuDir)] *] ] foreach file [lsort -dictionary $filelist] { if {[file isdirectory $file]} { $files insert end [file tail $file] $dates insert end {(Directory)} } } foreach file [lsort -dictionary $filelist] { if {![file isdirectory $file]} { set modified [clock format [file mtime $file] -format "%T %D"] $files insert end [file tail $file] $dates insert end $modified } } $expgui(FileDirButtonMenu) delete 0 end set list "" set dir "" foreach subdir [file split [set expgui(FileMenuDir)]] { set dir [file join $dir $subdir] lappend list $dir } foreach path $list { $expgui(FileDirButtonMenu) add command -label $path \ -command "[list set expgui(FileMenuDir) $path]; \ ChooseWinCnv $frm" } return } #------------------------------------------------------------------------------ # set options for liveplot proc liveplotopt {} { global liveplot expmap set frm .file catch {destroy $frm} toplevel $frm pack [frame [set frmA $frm.1] -bd 2 -relief groove] -padx 3 -pady 3 -side left set last [lindex [lsort -integer $expmap(powderlist)] end] if {$last == ""} {set last 1} pack [scale $frmA.1 -label "Histogram number" -from 1 -to $last \ -length 150 -orient horizontal -variable liveplot(hst)] -side top pack [checkbutton $frmA.2 -text {include plot legend}\ -variable liveplot(legend)] -side top pack [button $frm.2 -text OK \ -command {if ![catch {expr $liveplot(hst)}] "destroy .file"} \ ] -side top bind $frm {if ![catch {expr $liveplot(hst)}] "destroy .file"} # force the window to stay on top putontop $frm focus $frm.2 tkwait window $frm afterputontop } #------------------------------------------------------------------------------ # get an experiment file name #------------------------------------------------------------------------------ proc getExpFileName {mode} { global expgui set frm .file catch {destroy $frm} toplevel $frm wm title $frm "Experiment file" pack [frame [set frmA $frm.1] -bd 2 -relief groove] -padx 3 -pady 3 -side left pack [frame [set frmC $frm.3] ] -padx 3 -pady 3 -side left pack [label $frmC.2 -text "Sort .EXP files by" ] -side top pack [radiobutton $frmC.1 -text "File Name" -value 1 \ -variable expgui(filesort) -command "ChooseExpFil $frmA"] -side top pack [radiobutton $frmC.0 -text "Mod. Date" -value 0 \ -variable expgui(filesort) -command "ChooseExpFil $frmA"] -side top pack [button $frmC.b -text Read \ -command "valid_exp_file $frmA $mode"] -side top if {$mode == "new"} { $frmC.b config -text Save } pack [button $frmC.q -text Quit \ -command "set expgui(FileMenuEXPNAM) {}; destroy $frm"] -side top bind $frm "$frmC.b invoke" if {$mode == "new"} { pack [label $frmA.0 -text "Enter an experiment file to create"] \ -side top -anchor center } else { pack [label $frmA.0 -text "Select an experiment file to read"] \ -side top -anchor center } expfilebox $frmA $mode # force the window to stay on top putontop $frm focus $frmC.b tkwait window $frm afterputontop if {$expgui(FileMenuEXPNAM) == ""} return return [file join $expgui(FileMenuDir) $expgui(FileMenuEXPNAM)] } # validation routine proc valid_exp_file {frm mode} { global expgui tcl_platform # windows fixes if {$tcl_platform(platform) == "windows"} { # change backslashes to something sensible regsub -all {\\} $expgui(FileMenuEXPNAM) / expgui(FileMenuEXPNAM) # allow entry of D: for D:/ and D:TEST for d:/TEST if {[string first : $expgui(FileMenuEXPNAM)] != -1 && \ [string first :/ $expgui(FileMenuEXPNAM)] == -1} { regsub : $expgui(FileMenuEXPNAM) :/ expgui(FileMenuEXPNAM) } } if {$expgui(FileMenuEXPNAM) == ""} { set expgui(FileMenuDir) [file dirname [set expgui(FileMenuDir)] ] ChooseExpFil $frm return } elseif [file isdirectory \ [file join $expgui(FileMenuDir) $expgui(FileMenuEXPNAM)]] { if {$expgui(FileMenuEXPNAM) != "."} { set expgui(FileMenuDir) \ [file join $expgui(FileMenuDir) $expgui(FileMenuEXPNAM)] } ChooseExpFil $frm return } set expgui(FileMenuEXPNAM) [string toupper $expgui(FileMenuEXPNAM)] if {[file extension $expgui(FileMenuEXPNAM)] == ""} { append expgui(FileMenuEXPNAM) ".EXP" } if {[file extension $expgui(FileMenuEXPNAM)] != ".EXP"} { tk_dialog .expFileErrorMsg "File Open Error" \ "File [file tail $expgui(FileMenuEXPNAM)] is not a valid name. Experiment files must end in \".EXP\"" \ error 0 OK return } set file [file join $expgui(FileMenuDir) $expgui(FileMenuEXPNAM)] if {$mode == "new" && [file exists $file]} { set ans [tk_dialog .expFileErrorMsg "File Open Error" \ "File [file tail $file] already exists in [file dirname $file]. OK to overwrite?" question 0 \ "Select other name" "Overwrite"] if $ans {destroy .file} return } if {$mode == "old" && ![file exists $file]} { set ans [tk_dialog .expFileErrorMsg "File Open Error" \ "File [file tail $file] does not exist in [file dirname $file]. OK to create?" question 0 \ "Select other name" "Create"] if $ans {destroy .file} return } destroy .file } proc updir {} { global expgui set expgui(FileMenuDir) [file dirname [set expgui(FileMenuDir)]] } # create a file box proc expfilebox {bx mode} { global expgui pack [frame $bx.top] -side top pack [label $bx.top.a -text "Directory" ] -side left set expgui(FileDirButtonMenu) [tk_optionMenu $bx.top.d expgui(FileMenuDir) [pwd] ] pack $bx.top.d -side left set expgui(FileMenuDir) [pwd] # the icon below is from tk8.0/tkfbox.tcl set upfolder [image create bitmap -data { #define updir_width 28 #define updir_height 16 static char updir_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x01, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0x07, 0x00, 0x01, 0x90, 0x0f, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0x02, 0x00, 0x01, 0x10, 0xfe, 0x07, 0x01, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0xf0, 0xff, 0xff, 0x01};}] pack [button $bx.top.b -image $upfolder \ -command "updir; ChooseExpFil $bx" ] pack [frame $bx.a -width 200 -height 75] -side top -expand yes -fill both listbox $bx.a.files -relief raised -bd 2 \ -yscrollcommand "sync2boxes $bx.a.files $bx.a.dates $bx.a.scroll" \ -height 15 -width 0 listbox $bx.a.dates -relief raised -bd 2 \ -yscrollcommand "sync2boxes $bx.a.dates $bx.a.files $bx.a.scroll" \ -height 15 -width 0 -takefocus 0 scrollbar $bx.a.scroll -command "move2boxesY \" $bx.a.files $bx.a.dates \" " ChooseExpFil $bx bind $bx.a.files "ReleaseExpFil $bx" bind $bx.a.dates "ReleaseExpFil $bx" bind $bx.a.files "SelectExpFil $bx $mode" bind $bx.a.dates "SelectExpFil $bx $mode" pack $bx.a.scroll -side left -fill y pack $bx.a.files $bx.a.dates -side left -fill both -expand yes pack [entry $bx.c -textvariable expgui(FileMenuEXPNAM)] -side top } proc sync2boxes {master slave scroll args} { $slave yview moveto [lindex [$master yview] 0] eval $scroll set $args } proc move2boxesY {boxlist args} { foreach listbox $boxlist { eval $listbox yview $args } } # set the box or file in the selection window proc ReleaseExpFil {frm} { global expgui set files $frm.a.files set dates $frm.a.dates set select [$files curselection] if {$select == ""} { set select [$dates curselection] } if {$select == ""} { set expgui(FileMenuEXPNAM) "" } else { set expgui(FileMenuEXPNAM) [string trim [$files get $select]] } if {$expgui(FileMenuEXPNAM) == ""} { set expgui(FileMenuDir) [file dirname $expgui(FileMenuDir)] ChooseExpFil $frm } elseif [file isdirectory \ [file join [set expgui(FileMenuDir)] $expgui(FileMenuEXPNAM)]] { if {$expgui(FileMenuEXPNAM) != "."} { set expgui(FileMenuDir) [file join $expgui(FileMenuDir) $expgui(FileMenuEXPNAM)] ChooseExpFil $frm } } return } # select a file or directory -- called on double click proc SelectExpFil {frm mode} { global expgui set files $frm.a.files set dates $frm.a.dates set select [$files curselection] if {$select == ""} { set select [$dates curselection] } if {$select == ""} { set file . } else { set file [string trim [$files get $select]] } if {$file == ""} { set expgui(FileMenuDir) [file dirname [set expgui(FileMenuDir)] ] ChooseExpFil $frm } elseif [file isdirectory [file join [set expgui(FileMenuDir)] $file]] { if {$file != "."} { set expgui(FileMenuDir) [file join [set expgui(FileMenuDir)] $file] ChooseExpFil $frm } } else { set expgui(FileMenuEXPNAM) [file tail $file] valid_exp_file $frm $mode } } # fill the files & dates & Directory selection box with current directory, # also called when box is created to fill it proc ChooseExpFil {frm} { global expgui set files $frm.a.files set dates $frm.a.dates set expgui(FileMenuEXPNAM) {} $files delete 0 end $dates delete 0 end $files insert end {} $dates insert end {(Directory)} set filelist [glob -nocomplain \ [file join [set expgui(FileMenuDir)] *] ] foreach file [lsort -dictionary $filelist] { if {[file isdirectory $file]} { $files insert end [file tail $file] $dates insert end {(Directory)} } } set pairlist {} foreach file [lsort -dictionary $filelist] { if {![file isdirectory $file] && \ [string toupper [file extension $file]] == ".EXP"} { set modified [file mtime $file] lappend pairlist [list $file $modified] } } if {$expgui(filesort) == 0} { foreach pair [lsort -index 1 -integer $pairlist] { set file [lindex $pair 0] set modified [clock format [lindex $pair 1] -format "%T %D"] $files insert end [file tail $file] $dates insert end $modified } } else { foreach pair [lsort -index 0 $pairlist] { set file [lindex $pair 0] set modified [clock format [lindex $pair 1] -format "%T %D"] $files insert end [file tail $file] $dates insert end $modified } } $expgui(FileDirButtonMenu) delete 0 end set list "" set dir "" foreach subdir [file split [set expgui(FileMenuDir)]] { set dir [file join $dir $subdir] lappend list $dir } foreach path $list { $expgui(FileDirButtonMenu) add command -label $path \ -command "[list set expgui(FileMenuDir) $path]; \ ChooseExpFil $frm" } # highlight the current experiment -- if present for {set i 0} {$i < [$files size]} {incr i} { set file [$files get $i] if {$expgui(expfile) == [file join $expgui(FileMenuDir) $file]} { $files selection set $i } } return } proc putontop {w} { # center window $w above its parent and make it stay on top set wp [winfo parent $w] wm transient $w [winfo toplevel $wp] wm withdraw $w update idletasks # center the new window in the middle of the parent set x [expr [winfo x $wp] + [winfo width $wp]/2 - \ [winfo reqwidth $w]/2 - [winfo vrootx $wp]] if {$x < 0} {set x 0} set xborder 10 if {$x+[winfo reqwidth $w] +$xborder > [winfo screenwidth $w]} { incr x [expr \ [winfo screenwidth $w] - ($x+[winfo reqwidth $w] + $xborder)] } set y [expr [winfo y $wp] + [winfo height $wp]/2 - \ [winfo reqheight $w]/2 - [winfo vrooty $wp]] if {$y < 0} {set y 0} set yborder 25 if {$y+[winfo reqheight $w] +$yborder > [winfo screenheight $w]} { incr y [expr \ [winfo screenheight $w] - ($y+[winfo reqheight $w] + $yborder)] } wm geom $w +$x+$y wm deiconify $w global makenew set makenew(OldFocus) [focus] catch { set makenew(OldGrab) [grab current $w] if {$makenew(OldGrab) != ""} { set makenew(GrabStatus) [grab status $makenew(OldGrab)] } grab $w } } proc afterputontop {} { # restore focus global makenew catch {focus $makenew(OldFocus)} if {$makenew(OldGrab) != ""} { catch { if {$makenew(GrabStatus) == "global"} { grab -global $makenew(OldGrab) } else { grab $makenew(OldGrab) } } } } proc ShowBigMessage {win labeltext msg "optionlist OK"} { catch {destroy $win} toplevel $win # grab focus, etc. pack [label $win.l1 -text $labeltext] -side top pack [frame $win.f1] -side top -expand yes -fill both grid [text $win.f1.t \ -height 20 -width 55 -wrap none -font Courier \ -xscrollcommand "$win.f1.bscr set" \ -yscrollcommand "$win.f1.rscr set" \ ] -row 1 -column 0 -sticky news grid [scrollbar $win.f1.bscr -orient horizontal \ -command "$win.f1.t xview" \ ] -row 2 -column 0 -sticky ew grid [scrollbar $win.f1.rscr -command "$win.f1.t yview" \ ] -row 1 -column 1 -sticky ns # give extra space to the text box grid columnconfigure $win.f1 0 -weight 1 grid rowconfigure $win.f1 1 -weight 1 $win.f1.t insert end $msg global makenew set makenew(result) 0 bind $win "destroy $win" bind $win "$win.f1.t yview scroll -1 page" bind $win "$win.f1.t yview scroll 1 page" bind $win "$win.f1.t xview scroll 1 unit" bind $win "$win.f1.t xview scroll -1 unit" bind $win "$win.f1.t yview scroll -1 unit" bind $win "$win.f1.t yview scroll 1 unit" bind $win "$win.f1.t yview 0" bind $win "$win.f1.t yview end" set i 0 foreach item $optionlist { pack [button $win.q[incr i] \ -command "set makenew(result) $i; destroy $win" -text $item] -side left } putontop $win tkwait window $win # fix focus... afterputontop return $makenew(result) } #------------------------------------------------------------------------------ # Delete History Records proc DeleteHistoryRecords {{msg ""}} { global expgui set frm .history catch {destroy $frm} toplevel $frm if {[string trim $msg] == ""} { set msg "There are [CountHistory] history records" } pack [frame $frm.1 -bd 2 -relief groove] -padx 3 -pady 3 -side left pack [label $frm.1.0 -text $msg] -side top pack [frame $frm.1.1] -side top pack [label $frm.1.1.1 -text "Number of entries to keep"] -side left pack [entry $frm.1.1.2 -width 3 -textvariable expgui(historyKeep)\ ] -side left set expgui(historyKeep) 10 pack [checkbutton $frm.1.2 -text renumber -variable expgui(renumber)] -side top set expgui(renumber) 1 pack [frame $frm.2] -padx 3 -pady 3 -side left pack [button $frm.2.3 -text OK \ -command { if ![catch {expr $expgui(historyKeep)}] { DeleteHistory $expgui(historyKeep) $expgui(renumber) set expgui(changed) 1 destroy .history } }] -side top pack [button $frm.2.4 -text Quit \ -command {destroy .history}] -side top bind $frm "$frm.2.3 invoke" # force the window to stay on top putontop $frm focus $frm.2.3 tkwait window $frm afterputontop }