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

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