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

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