source: trunk/gui/scripts/analyzer.tcl @ 115

Last change on this file since 115 was 115, checked in by mmc, 19 years ago

Updated all copyright notices.

File size: 30.9 KB
RevLine 
[1]1# ----------------------------------------------------------------------
2#  COMPONENT: analyzer - output area for Rappture
3#
4#  This widget acts as the output side of a Rappture application.
5#  When the input has changed, it displays a Simulate button that
6#  launches the simulation.  When a simulation is running, this
7#  area shows status.  When it is finished, the results appear
8#  in place of the button, according to the specs in the <analyze>
9#  XML data.
10# ======================================================================
11#  AUTHOR:  Michael McLennan, Purdue University
[115]12#  Copyright (c) 2004-2005  Purdue Research Foundation
13#
14#  See the file "license.terms" for information on usage and
15#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
[1]16# ======================================================================
17package require Itk
18
[69]19option add *Analyzer.width 4i widgetDefault
20option add *Analyzer.height 4i widgetDefault
[11]21option add *Analyzer.simControl "auto" widgetDefault
22option add *Analyzer.simControlBackground "" widgetDefault
23option add *Analyzer.simControlOutline gray widgetDefault
24option add *Analyzer.simControlActiveBackground #ffffcc widgetDefault
25option add *Analyzer.simControlActiveOutline black widgetDefault
26
27option add *Analyzer.font \
28    -*-helvetica-medium-r-normal-*-*-120-* widgetDefault
[1]29option add *Analyzer.textFont \
30    -*-helvetica-medium-r-normal-*-*-120-* widgetDefault
[11]31option add *Analyzer.boldTextFont \
32    -*-helvetica-bold-r-normal-*-*-120-* widgetDefault
[1]33
34itcl::class Rappture::Analyzer {
35    inherit itk::Widget
36
[11]37    itk_option define -textfont textFont Font ""
38    itk_option define -boldtextfont boldTextFont Font ""
39    itk_option define -simcontrol simControl SimControl ""
40    itk_option define -simcontroloutline simControlOutline Background ""
41    itk_option define -simcontrolbackground simControlBackground Background ""
42    itk_option define -simcontrolactiveoutline simControlActiveOutline Background ""
43    itk_option define -simcontrolactivebackground simControlActiveBackground Background ""
[1]44    itk_option define -holdwindow holdWindow HoldWindow ""
45
[11]46    constructor {tool args} { # defined below }
[1]47    destructor { # defined below }
48
[11]49    public method simulate {args}
[1]50    public method reset {}
51    public method load {file}
[11]52    public method clear {}
[50]53    public method download {}
[1]54
[11]55    protected method _plot {args}
56    protected method _reorder {comps}
57    protected method _autoLabel {xmlobj path title cntVar}
[1]58    protected method _fixResult {}
[11]59    protected method _fixSize {}
60    protected method _fixSimControl {}
61    protected method _simState {state args}
[23]62    protected method _simOutput {message}
[1]63
[11]64    private variable _tool ""          ;# belongs to this tool
[1]65    private variable _control "manual" ;# start mode
[11]66    private variable _runs ""          ;# list of XML objects with results
67    private variable _pages 0          ;# number of pages for result sets
68    private variable _label2page       ;# maps output label => result set
69    private variable _plotlist ""      ;# items currently being plotted
[1]70
71    private common job                 ;# array var used for blt::bgexec jobs
72}
73                                                                               
74itk::usual Analyzer {
75    keep -background -cursor foreground -font
76}
77
78# ----------------------------------------------------------------------
79# CONSTRUCTOR
80# ----------------------------------------------------------------------
[11]81itcl::body Rappture::Analyzer::constructor {tool args} {
82    set _tool $tool
83
84    itk_option add hull.width hull.height
85    pack propagate $itk_component(hull) no
86
87    frame $itk_interior.simol -borderwidth 1 -relief flat
88    pack $itk_interior.simol -fill x
89
90    frame $itk_interior.simol.simbg -borderwidth 0
91    pack $itk_interior.simol.simbg -expand yes -fill both
92
93    itk_component add simulate {
94        button $itk_interior.simol.simbg.simulate -text "Simulate" \
95            -command [itcl::code $this simulate]
96    }
97    pack $itk_component(simulate) -side left -padx 4 -pady 4
98
99    itk_component add simstatus {
100        text $itk_interior.simol.simbg.simstatus -borderwidth 0 \
101            -highlightthickness 0 -height 1 -width 1 -wrap none \
102            -state disabled
103    } {
104        usual
105        ignore -highlightthickness
106        rename -font -textfont textFont Font
107    }
108    pack $itk_component(simstatus) -side left -expand yes -fill x
109
110    $itk_component(simstatus) tag configure popup \
111        -underline 1 -foreground blue
112
113    $itk_component(simstatus) tag bind popup \
114        <Enter> {%W configure -cursor center_ptr}
115    $itk_component(simstatus) tag bind popup \
116        <Leave> {%W configure -cursor ""}
117    $itk_component(simstatus) tag bind popup \
118        <ButtonPress> {after idle {Rappture::Tooltip::tooltip show %W}}
119
120
[1]121    itk_component add notebook {
122        Rappture::Notebook $itk_interior.nb
123    }
124    pack $itk_interior.nb -expand yes -fill both
125
126    # ------------------------------------------------------------------
[11]127    # ABOUT PAGE
128    # ------------------------------------------------------------------
129    set w [$itk_component(notebook) insert end about]
130
131    Rappture::Scroller $w.info -xscrollmode off -yscrollmode auto
132    pack $w.info -expand yes -fill both -padx 4 -pady 20
133    itk_component add toolinfo {
134        text $w.info.text -width 1 -height 1 -wrap word \
135            -borderwidth 0 -highlightthickness 0
136    } {
137        usual
138        ignore -borderwidth -relief
139        rename -font -textfont textFont Font
140    }
141    $w.info contents $w.info.text
142
143    # ------------------------------------------------------------------
[1]144    # SIMULATION PAGE
145    # ------------------------------------------------------------------
146    set w [$itk_component(notebook) insert end simulate]
147    frame $w.cntls
[11]148    pack $w.cntls -side bottom -fill x -pady 12
149    frame $w.cntls.sep -background black -height 1
150    pack $w.cntls.sep -side top -fill x
[1]151
[11]152    itk_component add abort {
153        button $w.cntls.abort -text "Abort" \
154            -command [itcl::code $_tool abort]
[1]155    }
[11]156    pack $itk_component(abort) -side left -expand yes -padx 4 -pady 4
[1]157
158    Rappture::Scroller $w.info -xscrollmode off -yscrollmode auto
[11]159    pack $w.info -expand yes -fill both -padx 4 -pady 4
160    itk_component add runinfo {
[95]161        text $w.info.text -width 1 -height 1 -wrap none \
[1]162            -borderwidth 0 -highlightthickness 0 \
163            -state disabled
164    } {
165        usual
166        ignore -borderwidth -relief
167        rename -font -textfont textFont Font
168    }
169    $w.info contents $w.info.text
170
[23]171    $itk_component(runinfo) tag configure ERROR -foreground red
172
173    itk_component add progress {
174        Rappture::Progress $w.progress
175    }
176
[1]177    # ------------------------------------------------------------------
178    # ANALYZE PAGE
179    # ------------------------------------------------------------------
180    set w [$itk_component(notebook) insert end analyze]
181
[11]182    frame $w.top
183    pack $w.top -side top -fill x -pady 8
184    label $w.top.l -text "Result:" -font $itk_option(-font)
185    pack $w.top.l -side left
186
[1]187    itk_component add resultselector {
[11]188        Rappture::Combobox $w.top.sel -width 50 -editable no
[1]189    } {
190        usual
191        rename -font -textfont textFont Font
192    }
[11]193    pack $itk_component(resultselector) -side left -expand yes -fill x
[1]194    bind $itk_component(resultselector) <<Value>> [itcl::code $this _fixResult]
195
[50]196    if {[Rappture::filexfer::enabled]} {
197        itk_component add download {
198            button $w.top.dl -text "Download..." \
199                -command [itcl::code $this download]
200        }
201        pack $itk_component(download) -side right -padx {4 0}
202        Rappture::Tooltip::for $itk_component(download) "Downloads the current result to a new web browser window on your desktop.  From there, you can easily print or save results."
203    }
204
[1]205    itk_component add results {
[11]206        Rappture::Panes $w.pane
[1]207    }
[11]208    pack $itk_component(results) -expand yes -fill both
209    set f [$itk_component(results) pane 0]
[1]210
[11]211    itk_component add resultpages {
212        Rappture::Notebook $f.nb
213    }
214    pack $itk_component(resultpages) -expand yes -fill both
215
216    set f [$itk_component(results) insert end -fraction 0.1]
217    itk_component add resultset {
218        Rappture::ResultSet $f.rset \
219            -clearcommand [itcl::code $this clear] \
220            -settingscommand [itcl::code $this _plot] \
221            -promptcommand [itcl::code $this _simState]
222    }
223    pack $itk_component(resultset) -expand yes -fill both
224    bind $itk_component(resultset) <<Control>> [itcl::code $this _fixSize]
225
[1]226    eval itk_initialize $args
[11]227
228    #
229    # Load up tool info on the first page.
230    #
231    $itk_component(toolinfo) tag configure title \
232        -font $itk_option(-boldtextfont)
233
234    set mesg [$tool xml get tool.title]
235    if {"" != $mesg} {
236        $itk_component(toolinfo) insert end $mesg title
237        $itk_component(toolinfo) insert end "\n\n"
238    }
239
240    set mesg [$tool xml get tool.about]
241    if {"" != $mesg} {
242        $itk_component(toolinfo) insert end $mesg
243    }
244    $itk_component(toolinfo) configure -state disabled
245    $itk_component(notebook) current about
246
247    # tool can run on "manual" (default) or "auto"
248    set cntl [$tool xml get tool.control]
[22]249    if {"" == $cntl} {
250        set cntl [$tool xml get tool.control.type]
251    }
[11]252    if {"" != $cntl} {
253        set _control $cntl
254    }
[12]255
256    # reset everything to a clean state
257    reset
[1]258}
259
260# ----------------------------------------------------------------------
261# DESTRUCTOR
262# ----------------------------------------------------------------------
263itcl::body Rappture::Analyzer::destructor {} {
[11]264    foreach obj $_runs {
265        itcl::delete object $obj
[1]266    }
[11]267    after cancel [itcl::code $this simulate]
[1]268}
269
270# ----------------------------------------------------------------------
[11]271# USAGE: simulate ?-ifneeded?
272# USAGE: simulate ?<path1> <value1> <path2> <value2> ...?
[1]273#
[11]274# Kicks off the simulator by executing the tool.command associated
275# with the tool.  If any arguments are specified, they are used to
276# set parameters for the simulation.  While the simulation is running,
277# it shows status.  When the simulation is finished, it switches
278# automatically to "analyze" mode and shows the results.
[1]279# ----------------------------------------------------------------------
[11]280itcl::body Rappture::Analyzer::simulate {args} {
281    if {$args == "-ifneeded"} {
282        # check to see if simulation is really needed
283        $_tool sync
284        if {[$itk_component(resultset) contains [$_tool xml object]]} {
285            # not needed -- show results and return
286            $itk_component(notebook) current analyze
287            return
[1]288        }
[11]289        set args ""
290    }
[1]291
[11]292    # simulation is needed -- go to simulation page
293    $itk_component(notebook) current simulate
[1]294
[23]295    # no progress messages yet
296    pack forget $itk_component(progress)
297    lappend args -output [itcl::code $this _simOutput]
298
[11]299    _simState off
300    $itk_component(runinfo) configure -state normal
301    $itk_component(runinfo) delete 1.0 end
[23]302    $itk_component(runinfo) insert end "Running simulation...\n\n"
[11]303    $itk_component(runinfo) configure -state disabled
[1]304
[11]305    # if the hold window is set, then put up a busy cursor
306    if {$itk_option(-holdwindow) != ""} {
307        blt::busy hold $itk_option(-holdwindow)
308        raise $itk_component(hull)
309        update
310    }
[1]311
[11]312    # execute the job
313    foreach {status result} [eval $_tool run $args] break
[1]314
[11]315    # if job was aborted, then allow simulation again
316    if {$result == "ABORT"} {
317        _simState on "Aborted"
318    }
[1]319
[11]320    # read back the results from run.xml
321    if {$status == 0 && $result != "ABORT"} {
322        if {[regexp {=RAPPTURE-RUN=>([^\n]+)} $result match file]} {
323            set status [catch {load $file} msg]
324            if {$status != 0} {
[43]325                global errorInfo
326                set result "$msg\n$errorInfo"
[1]327            }
328        } else {
[11]329            set status 1
330            set result "Can't find result file in output:\n\n$result"
[1]331        }
332    }
[11]333
334    # back to normal
335    if {$itk_option(-holdwindow) != ""} {
336        blt::busy release $itk_option(-holdwindow)
337    }
338    $itk_component(abort) configure -state disabled
339
340    if {$status != 0} {
341        $itk_component(runinfo) configure -state normal
342        $itk_component(runinfo) delete 1.0 end
343        $itk_component(runinfo) insert end "Problem launching job:\n\n"
[43]344        _simOutput $result
[11]345        $itk_component(runinfo) configure -state disabled
[43]346        $itk_component(runinfo) see 1.0
[11]347    } else {
348        $itk_component(notebook) current analyze
349    }
[1]350}
351
352# ----------------------------------------------------------------------
353# USAGE: reset
354#
355# Used to reset the analyzer whenever the input to a simulation has
356# changed.  Sets the mode back to "simulate", so the user has to
357# simulate again to see the output.  If the <start> option is set
358# to "auto", the simulation is invoked immediately.
359# ----------------------------------------------------------------------
360itcl::body Rappture::Analyzer::reset {} {
[11]361    # check to see if simulation is really needed
362    $_tool sync
363    if {![$itk_component(resultset) contains [$_tool xml object]]} {
364        # if control mode is "auto", then simulate right away
365        if {[string match auto* $_control]} {
366            # auto control -- don't need button
367            pack forget $itk_interior.simol
[1]368
[11]369            after cancel [itcl::code $this simulate]
370            after idle [itcl::code $this simulate]
371        } else {
372            _simState on "new input parameters"
373        }
374    } else {
375        _simState off
[1]376    }
377}
378
379# ----------------------------------------------------------------------
380# USAGE: load <file>
381#
[11]382# Loads the data from the given <file> into the appropriate results
383# sets.  If necessary, new results sets are created to store the data.
[1]384# ----------------------------------------------------------------------
385itcl::body Rappture::Analyzer::load {file} {
[43]386    # only show the last result? then clear first
387    if {[$_tool xml get tool.analyzer] == "last"} {
388        clear
389    }
390
[11]391    # try to load new results from the given file
392    set xmlobj [Rappture::library $file]
393    lappend _runs $xmlobj
394
395    # go through the analysis and find all result sets
396    set haveresults 0
397    foreach item [_reorder [$xmlobj children output]] {
398        switch -glob -- $item {
399            log* {
400                _autoLabel $xmlobj output.$item "Output Log" counters
401            }
[64]402            string* {
403                _autoLabel $xmlobj output.$item "String" counters
404            }
[11]405            curve* - field* {
406                _autoLabel $xmlobj output.$item "Plot" counters
407            }
[22]408            structure* {
409                _autoLabel $xmlobj output.$item "Structure" counters
410            }
[11]411            table* {
412                _autoLabel $xmlobj output.$item "Energy Levels" counters
413            }
414        }
[13]415        set label [$xmlobj get output.$item.about.group]
416        if {"" == $label} {
417            set label [$xmlobj get output.$item.about.label]
418        }
[11]419
[17]420        set hidden [$xmlobj get output.$item.hide]
421        set hidden [expr {"" != $hidden && $hidden}]
422
423        if {"" != $label && !$hidden} {
[11]424            set haveresults 1
425        }
[1]426    }
427
[11]428    # if there are any valid results, add them to the resultset
429    if {$haveresults} {
430        set size [$itk_component(resultset) size]
[13]431        set index [$itk_component(resultset) add $xmlobj]
[1]432
[11]433        # add each result to a result viewer
434        foreach item [_reorder [$xmlobj children output]] {
[13]435            set label [$xmlobj get output.$item.about.group]
436            if {"" == $label} {
437                set label [$xmlobj get output.$item.about.label]
438            }
[11]439
[17]440            set hidden [$xmlobj get output.$item.hide]
441            set hidden [expr {"" != $hidden && $hidden}]
442
443            if {"" != $label && !$hidden} {
[11]444                if {![info exists _label2page($label)]} {
445                    set name "page[incr _pages]"
446                    set page [$itk_component(resultpages) insert end $name]
447                    set _label2page($label) $page
448                    Rappture::ResultViewer $page.rviewer
449                    pack $page.rviewer -expand yes -fill both -pady 4
450
451                    $itk_component(resultselector) choices insert end \
452                        $name $label
453                }
454
455                # add/replace the latest result into this viewer
456                set page $_label2page($label)
[13]457
458                if {![info exists reset($page)]} {
459                    $page.rviewer clear $index
460                    set reset($page) 1
461                }
462                $page.rviewer add $index $xmlobj output.$item
[11]463            }
464        }
[1]465    }
[11]466
467    # show the first page by default
468    set first [$itk_component(resultselector) choices get -label 0]
469    if {$first != ""} {
[13]470        set page [$itk_component(resultselector) choices get -value 0]
471        $itk_component(resultpages) current $page
[11]472        $itk_component(resultselector) value $first
473    }
[1]474}
475
476# ----------------------------------------------------------------------
[11]477# USAGE: clear
[1]478#
[11]479# Discards all results previously loaded into the analyzer.
[1]480# ----------------------------------------------------------------------
[11]481itcl::body Rappture::Analyzer::clear {} {
482    foreach obj $_runs {
483        itcl::delete object $obj
484    }
485    set _runs ""
486
[13]487    $itk_component(resultset) clear
488    $itk_component(results) fraction end 0.1
489
[11]490    foreach label [array names _label2page] {
491        set page $_label2page($label)
492        $page.rviewer clear
493    }
[13]494    $itk_component(resultselector) value ""
495    $itk_component(resultselector) choices delete 0 end
496    catch {unset _label2page}
497    set _plotlist ""
[11]498
[13]499    #
500    # HACK ALERT!!
501    # The following statement should be in place, but it causes
502    # vtk to dump core.  Leave it out until we can fix the core dump.
503    # In the mean time, we leak memory...
504    #
505    #$itk_component(resultpages) delete -all
506    #set _pages 0
[11]507
508    _simState on
509    _fixSimControl
[12]510    reset
[11]511}
512
513# ----------------------------------------------------------------------
[50]514# USAGE: download
515#
516# Spools the current result so the user can download it.
517# ----------------------------------------------------------------------
518itcl::body Rappture::Analyzer::download {} {
519    if {[Rappture::filexfer::enabled]} {
520        set title [$itk_component(resultselector) value]
521        set page [$itk_component(resultselector) translate $title]
522        if {$page != ""} {
523            set ext ""
524            set f [$itk_component(resultpages) page $page]
525            foreach {ext data} [$f.rviewer download] break
526            if {"" == $ext} {
527                Rappture::Tooltip::cue $itk_component(download) \
528                    "Can't download this result."
529                return
530            }
531            regsub -all {[\ -\/\:-\@\{-\~]} $title {} title
532            set file "$title$ext"
533        } else {
534            # this shouldn't happen
535            set file error.html
536            set data "<h1>Not Found</h1>There is no result selected."
537        }
538
539        if {[catch {Rappture::filexfer::spool $data $file} result]} {
540            if {"no clients" == $result} {
541                Rappture::Tooltip::cue $itk_component(download) \
542                    "Can't download this result.  Looks like you might be having trouble with the version of Java installed for your browser."
543            } else {
544                error $result "    (while spooling result \"$title\")"
545            }
546        }
547    }
548}
549
550# ----------------------------------------------------------------------
[11]551# USAGE: _plot ?<index> <options> <index> <options>...?
552#
553# Used internally to update the plot shown in the current result
554# viewer whenever the resultset settings have changed.  Causes the
555# desired results to show up on screen.
556# ----------------------------------------------------------------------
557itcl::body Rappture::Analyzer::_plot {args} {
558    set _plotlist $args
559
[1]560    set page [$itk_component(resultselector) value]
561    set page [$itk_component(resultselector) translate $page]
[43]562    if {"" != $page} {
563        set f [$itk_component(resultpages) page $page]
564        $f.rviewer plot clear
565        foreach {index opts} $_plotlist {
566            $f.rviewer plot add $index $opts
567        }
[11]568    }
[1]569}
570
571# ----------------------------------------------------------------------
[13]572# USAGE: _reorder <compList>
[1]573#
[11]574# Used internally to change the order of a series of output components
575# found in the <output> section.  Moves the <log> elements to the end
576# and returns the updated list.
[1]577# ----------------------------------------------------------------------
[11]578itcl::body Rappture::Analyzer::_reorder {comps} {
579    set i 0
580    set max [llength $comps]
581    while {$i < $max} {
582        set c [lindex $comps $i]
583        if {[string match log* $c]} {
584            set comps [lreplace $comps $i $i]
585            lappend comps $c
586            incr max -1
587        } else {
588            incr i
589        }
[1]590    }
[11]591    return $comps
[1]592}
593
594# ----------------------------------------------------------------------
[11]595# USAGE: _autoLabel <xmlobj> <path> <title> <cntVar>
[1]596#
[11]597# Used internally to check for an about.label property at the <path>
598# in <xmlobj>.  If this object doesn't have a label, then one is
599# supplied using the given <title>.  The <cntVar> is an array of
600# counters in the calling scopes for titles that have been used
601# in the past.  This is used to create titles like "Plot #2" the
602# second time it is encountered.
603#
604# The <xmlobj> is updated so that the label is inserted directly in
605# the tree.
[1]606# ----------------------------------------------------------------------
[11]607itcl::body Rappture::Analyzer::_autoLabel {xmlobj path title cntVar} {
608    upvar $cntVar counters
609
[13]610    set group [$xmlobj get $path.about.group]
[11]611    set label [$xmlobj get $path.about.label]
612    if {"" == $label} {
613        # no label -- make one up using the title specified
[13]614        if {![info exists counters($group-$title)]} {
615            set counters($group-$title) 1
[11]616            set label $title
617        } else {
[13]618            set label "$title (#[incr counters($group-$title)])"
[11]619        }
620        $xmlobj put $path.about.label $label
621    } else {
622        # handle the case of two identical labels in <output>
[13]623        if {![info exists counters($group-$label)]} {
624            set counters($group-$label) 1
[11]625        } else {
[13]626            set label "$label (#[incr counters($group-$label)])"
[11]627            $xmlobj put $path.about.label $label
628        }
[1]629    }
[11]630    return $label
[1]631}
632
633# ----------------------------------------------------------------------
[11]634# USAGE: _fixResult
[1]635#
[11]636# Used internally to change the result page being displayed whenever
637# the user selects a page from the results combobox.
[1]638# ----------------------------------------------------------------------
[11]639itcl::body Rappture::Analyzer::_fixResult {} {
640    set page [$itk_component(resultselector) value]
641    set page [$itk_component(resultselector) translate $page]
[13]642    if {$page != ""} {
[64]643        blt::busy hold [winfo toplevel $itk_component(hull)]; update idletasks
[13]644        $itk_component(resultpages) current $page
[11]645
[13]646        set f [$itk_component(resultpages) page $page]
647        $f.rviewer plot clear
648        eval $f.rviewer plot add $_plotlist
[64]649        blt::busy release [winfo toplevel $itk_component(hull)]
[13]650    }
[11]651}
652
653# ----------------------------------------------------------------------
654# USAGE: _fixSize
655#
656# Used internally to change the size of the result set area whenever
657# a new control appears.  Adjusts the size available for the result
658# set up to some maximum.
659# ----------------------------------------------------------------------
660itcl::body Rappture::Analyzer::_fixSize {} {
661    set f [$itk_component(results) fraction end]
662    if {$f < 0.4} {
663        $itk_component(results) fraction end [expr {$f+0.15}]
[1]664    }
[11]665    _fixSimControl
666}
[1]667
[11]668# ----------------------------------------------------------------------
669# USAGE: _simState <boolean> ?<message>? ?<settings>?
670#
671# Used internally to change the "Simulation" button on or off.
672# If the <boolean> is on, then any <message> and <settings> are
673# displayed as well.  The <message> is a note to the user about
674# what will be simulated, and the <settings> are a list of
675# tool parameter settings of the form {path1 val1 path2 val2 ...}.
676# When these are in place, the next Simulate operation will use
677# these settings.  This helps fill in missing data values.
678# ----------------------------------------------------------------------
679itcl::body Rappture::Analyzer::_simState {state args} {
680    if {$state} {
681        $itk_interior.simol configure \
682            -background $itk_option(-simcontrolactiveoutline)
683        $itk_interior.simol.simbg configure \
684            -background $itk_option(-simcontrolactivebackground)
685        $itk_component(simulate) configure \
686            -highlightbackground $itk_option(-simcontrolactivebackground)
687        $itk_component(simstatus) configure \
688            -background $itk_option(-simcontrolactivebackground)
[1]689
[11]690        $itk_component(abort) configure -state disabled
691        $itk_component(simulate) configure -state normal \
692            -command [itcl::code $this simulate]
[1]693
[11]694        #
695        # If there's a special message, then put it up next to the button.
696        #
697        set mesg [lindex $args 0]
698        if {"" != $mesg} {
699            $itk_component(simstatus) configure -state normal
700            $itk_component(simstatus) delete 1.0 end
701            $itk_component(simstatus) insert end $mesg
[1]702
[11]703            #
704            # If there are any settings, then install them in the
705            # "Simulate" button.  Also, pop them up as a tooltip
706            # for the message.
707            #
708            set settings [lindex $args 1]
709            if {[llength $settings] > 0} {
710                $itk_component(simulate) configure \
711                    -command [eval itcl::code $this simulate $settings]
[8]712
[11]713                set details ""
714                foreach {path val} $settings {
715                    set str [$_tool xml get $path.about.label]
716                    if {"" == $str} {
717                        set str [$_tool xml element -as id $path]
718                    }
719                    append details "$str = $val\n"
720                }
721                set details [string trim $details]
[8]722
[11]723                Rappture::Tooltip::for $itk_component(simstatus) $details
724                $itk_component(simstatus) insert end " "
725                $itk_component(simstatus) insert end "(details...)" popup
[8]726            }
[11]727            $itk_component(simstatus) configure -state disabled
[1]728        }
[11]729    } else {
730        if {"" != $itk_option(-simcontrolbackground)} {
731            set simcbg $itk_option(-simcontrolbackground)
732        } else {
733            set simcbg $itk_option(-background)
734        }
735        $itk_interior.simol configure \
736            -background $itk_option(-simcontroloutline)
737        $itk_interior.simol.simbg configure -background $simcbg
738        $itk_component(simulate) configure -highlightbackground $simcbg
739        $itk_component(simstatus) configure -background $simcbg
[1]740
[11]741        $itk_component(simulate) configure -state disabled
742        $itk_component(abort) configure -state normal
743
744        $itk_component(simstatus) configure -state normal
745        $itk_component(simstatus) delete 1.0 end
746        $itk_component(simstatus) configure -state disabled
747        Rappture::Tooltip::for $itk_component(simstatus) ""
[1]748    }
[11]749}
[1]750
[11]751# ----------------------------------------------------------------------
[23]752# USAGE: _simOutput <message>
753#
754# Invoked automatically whenever output comes in while running the
755# tool.  Extracts any =RAPPTURE-???=> messages from the output and
756# sends the output to the display.  For example, any
757# =RAPPTURE-PROGRESS=> message pops up the progress meter and updates
758# it to show the latest progress message.  This is useful for
759# long-running tools, to let the user know how much longer the
760# simulation will take.
761# ----------------------------------------------------------------------
762itcl::body Rappture::Analyzer::_simOutput {message} {
763    #
764    # Scan through and pick out any =RAPPTURE-PROGRESS=> messages first.
765    #
766    while {[regexp -indices \
767               {=RAPPTURE-PROGRESS=>([0-9]+) +([^\n]*)(\n|$)} $message \
768                match percent mesg]} {
769
770        foreach {i0 i1} $percent break
771        set percent [string range $message $i0 $i1]
772
773        foreach {i0 i1} $mesg break
774        set mesg [string range $message $i0 $i1]
775
776        pack $itk_component(progress) -fill x -padx 10 -pady 10
777        $itk_component(progress) settings -percent $percent -message $mesg
778
779        foreach {i0 i1} $match break
780        set message [string replace $message $i0 $i1]
781    }
782
783    #
784    # Break up the remaining lines according to =RAPPTURE-ERROR=> messages.
785    # Show errors in a special color.
786    #
787    $itk_component(runinfo) configure -state normal
788
789    while {[regexp -indices \
790               {=RAPPTURE-([a-zA-Z]+)=>([^\n]*)(\n|$)} $message \
791                match type mesg]} {
792
793        foreach {i0 i1} $match break
794        set first [string range $message 0 [expr {$i0-1}]]
795        if {[string length $first] > 0} {
796            $itk_component(runinfo) insert end $first
797            $itk_component(runinfo) insert end \n
798        }
799
800        foreach {t0 t1} $type break
801        set type [string range $message $t0 $t1]
802        foreach {m0 m1} $mesg break
803        set mesg [string range $message $m0 $m1]
804        if {[string length $mesg] > 0 && $type != "RUN"} {
805            $itk_component(runinfo) insert end $mesg $type
806            $itk_component(runinfo) insert end \n $type
807        }
808
809        set message [string range $message [expr {$i1+1}] end]
810    }
811
812    if {[string length $message] > 0} {
813        $itk_component(runinfo) insert end $message
814        if {[$itk_component(runinfo) get end-2char] != "\n"} {
815            $itk_component(runinfo) insert end "\n"
816        }
817        $itk_component(runinfo) see end
818    }
819    $itk_component(runinfo) configure -state disabled
820}
821
822# ----------------------------------------------------------------------
[11]823# USAGE: _fixSimControl
824#
825# Used internally to add or remove the simulation control at the
826# top of the analysis area.  This is controlled by the -simcontrol
827# option.
828# ----------------------------------------------------------------------
829itcl::body Rappture::Analyzer::_fixSimControl {} {
830    switch -- $itk_option(-simcontrol) {
831        on {
832            pack $itk_interior.simol -fill x -before $itk_interior.nb
833        }
834        off {
835            pack forget $itk_interior.simol
836        }
837        auto {
838            #
839            # If we have two or more radiodials, then there is a
840            # chance of encountering a combination of parameters
841            # with no data, requiring simulation.
842            #
843            if {[$itk_component(resultset) size -controls] >= 2} {
844                pack $itk_interior.simol -fill x -before $itk_interior.nb
845            } else {
846                pack forget $itk_interior.simol
847            }
848        }
849        default {
850            error "bad value \"$itk_option(-simcontrol)\": should be on, off, auto"
851        }
[1]852    }
853}
[11]854
855# ----------------------------------------------------------------------
856# CONFIGURATION OPTION: -simcontrol
857#
858# Controls whether or not the Simulate button is showing.  In some
859# cases, it is not needed.
860# ----------------------------------------------------------------------
861itcl::configbody Rappture::Analyzer::simcontrol {
862    _fixSimControl
863}
Note: See TracBrowser for help on using the repository browser.