source: trunk/gui/scripts/main.tcl @ 3024

Last change on this file since 3024 was 3024, checked in by mmc, 12 years ago

Major rewrite of the Analyzer and management of results so that "Clear
One Result" will work properly--even with "analyzer last" and "control
manual-resim". The old ResultSet? widget is now a ResultSelector? widget
that takes a ResultSet? as a data object. The ResultSet? contains all
Rappture::LibraryObj? result objects and computes diffs between results.
The ResultSet? owns all objects; when a result is cleared from the
ResultSet?, the object is deleted. The ResultSet? notifies various
clients (ResultSelector? and Analyzer) whenever there are changes, such
as adding or clearing a result.

Fixed the core (scew) library to avoid ignoring whitespace and trimming
strings. This was causing problems with string values and MIME-encoded
images with trailing newlines. The original (with newlines) seemed like
a different value than the version in the run.xml file (without newlines).
Some simulators may depend on the newlines. The Tcl library version
preserves the newlines, so the scew version should too.

File size: 11.7 KB
Line 
1#!/bin/sh
2# ----------------------------------------------------------------------
3#  USER INTERFACE DRIVER
4#
5#  This driver program loads a tool description from a tool.xml file,
6#  and produces a user interface automatically to drive an application.
7#  The user can set up input, click and button to launch a tool, and
8#  browse through output.
9#
10#  RUN AS FOLLOWS:
11#    wish main.tcl ?-tool <toolfile>?
12#
13#  If the <toolfile> is not specified, it defaults to "tool.xml" in
14#  the current working directory.
15#
16# ======================================================================
17#  AUTHOR:  Michael McLennan, Purdue University
18#  Copyright (c) 2004-2011  Purdue Research Foundation
19#
20#  See the file "license.terms" for information on usage and
21#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
22# ======================================================================
23
24# take the main window down for now, so we can avoid a flash on the screen
25wm withdraw .
26
27package require Itcl
28package require Img
29package require Rappture
30package require RapptureGUI
31
32option add *MainWin.mode desktop startupFile
33option add *MainWin.borderWidth 0 startupFile
34option add *MainWin.anchor fill startupFile
35
36# "web site" look
37option add *MainWin.bgScript {
38    rectangle 0 0 200 <h> -outline "" -fill #5880BB
39    rectangle 200 0 300 <h> -outline "" -fill #425F8B
40    rectangle 300 0 <w> <h> -outline "" -fill #324565
41} startupFile
42
43# "clean" look
44option add *MainWin.bgScript "" startupFile
45option add *MainWin.bgColor white startupFile
46option add *Tooltip.background white
47option add *Editor.background white
48option add *Gauge.textBackground white
49option add *TemperatureGauge.textBackground white
50option add *Switch.textBackground white
51option add *Progress.barColor #ffffcc
52option add *Balloon.titleBackground #6666cc
53option add *Balloon.titleForeground white
54option add *Balloon*Label.font -*-helvetica-medium-r-normal-*-12-*
55option add *Balloon*Radiobutton.font -*-helvetica-medium-r-normal-*-12-*
56option add *Balloon*Checkbutton.font -*-helvetica-medium-r-normal-*-12-*
57option add *ResultSelector.controlbarBackground #6666cc
58option add *ResultSelector.controlbarForeground white
59option add *ResultSelector.activeControlBackground #ccccff
60option add *ResultSelector.activeControlForeground black
61option add *Radiodial.length 3i
62option add *BugReport*banner*foreground white
63option add *BugReport*banner*background #a9a9a9
64option add *BugReport*banner*highlightBackground #a9a9a9
65option add *BugReport*banner*font -*-helvetica-bold-r-normal-*-18-*
66option add *hubcntls*Button.padX 0 widgetDefault
67option add *hubcntls*Button.padY 0 widgetDefault
68option add *hubcntls*Button.relief flat widgetDefault
69option add *hubcntls*Button.overRelief raised widgetDefault
70option add *hubcntls*Button.borderWidth 1 widgetDefault
71option add *hubcntls*Button.font \
72    -*-helvetica-medium-r-normal-*-8-* widgetDefault
73
74switch $tcl_platform(platform) {
75    unix - windows {
76        event add <<PopupMenu>> <ButtonPress-3>
77    }
78    macintosh {
79        event add <<PopupMenu>> <Control-ButtonPress-1>
80    }
81}
82
83# install a better bug handler
84Rappture::bugreport::install
85# fix the "grab" command to support a stack of grab windows
86Rappture::grab::init
87
88#
89# Process command line args to get the names of files to load...
90#
91Rappture::getopts argv params {
92    value -tool tool.xml
93    list  -load ""
94    value -nosim 0
95}
96
97set loadobjs {}
98foreach runfile $params(-load) {
99    if {![file exists $runfile]} {
100        puts stderr "can't find run: \"$runfile\""
101        exit 1
102    }
103    set status [catch {Rappture::library $runfile} result]
104    lappend loadobjs $result
105}
106
107# open the XML file containing the tool parameters
108if {![file exists $params(-tool)]} {
109    # check to see if the user specified any run.xml files to load.
110    # if so, we can use that as the tool.xml. if we can find where
111    # the original application was installed using the xml tag
112    # tool.version.application.directory(top), the user can
113    # run new simulations, otherwise they can only revisualize the
114    # run.xml files they are loading.
115    set pseudotool ""
116    if {0 == [llength $loadobjs]} {
117        puts stderr "can't find tool \"$params(-tool)\""
118        exit 1
119    }
120    # search the loadfiles for the install location
121    # we could just use run.xml files as tool.xml, but
122    # if there are loaders or notes, they will still need
123    # examples/ and docs/ dirs from the install location
124    foreach runobj $loadobjs {
125        set tdir [$runobj get tool.version.application.directory(tool)]
126        if {[file isdirectory $tdir] && \
127            [file exists $tdir/tool.xml]} {
128            set pseudotool $tdir/tool.xml
129            break
130        }
131    }
132    if {![file exists $pseudotool]} {
133        # we didn't find a tool.xml file,
134        # use info from a runfile to build gui
135        # disable simulation, because no tool.xml
136        set pseudotool [lindex $params(-load) 0]
137        array set params [list -nosim true]
138    }
139    if {![file exists $pseudotool]} {
140        puts stderr "can't find tool \"$params(-tool)\""
141        exit 1
142    }
143    array set params [list -tool $pseudotool]
144}
145
146set xmlobj [Rappture::library $params(-tool)]
147
148set installdir [file dirname $params(-tool)]
149if {"." == $installdir} {
150    set installdir [pwd]
151}
152
153set tool [Rappture::Tool ::#auto $xmlobj $installdir]
154
155# ----------------------------------------------------------------------
156# CHECK JOB FAILURE REPORTING
157#
158# If this tool might fail when it launches jobs (i.e., Rappture
159# can't check some inputs, such as strings), then disable the
160# automatic ticket submission for job failures
161# ----------------------------------------------------------------------
162set val [$tool xml get tool.reportJobFailures]
163if { "" != $val} {
164    if {[catch {Rappture::bugreport::shouldReport jobfailures $val} result]} {
165        puts stderr "WARNING for reportJobFailures: $result"
166    }
167}
168
169# ----------------------------------------------------------------------
170# LOAD RESOURCE SETTINGS
171#
172# Try to load the $SESSIONDIR/resources file, which contains
173# middleware settings, such as the application name and the
174# filexfer settings.
175# ----------------------------------------------------------------------
176Rappture::resources::load
177
178# ----------------------------------------------------------------------
179# INITIALIZE THE DESKTOP CONNECTION
180#
181# If there's a SESSION ID, then this must be running within the
182# nanoHUB.  Try to initialize the server handling the desktop
183# connection.
184# ----------------------------------------------------------------------
185Rappture::filexfer::init
186
187# ----------------------------------------------------------------------
188# MAIN WINDOW
189# ----------------------------------------------------------------------
190Rappture::MainWin .main -borderwidth 0
191.main configure -title [$tool xml get tool.title]
192wm withdraw .main
193
194# if the FULLSCREEN variable is set, then nanoHUB wants us to go full screen
195if {[info exists env(FULLSCREEN)]} {
196    .main configure -mode web
197}
198
199#
200# The main window has a pager that acts as a notebook for the
201# various parts.  This notebook as at least two pages--an input
202# page and an output (analysis) page.  If there are <phase>'s
203# for input, then there are more pages in the notebook.
204#
205set win [.main component app]
206Rappture::Postern $win.postern
207pack $win.postern -side bottom -fill x
208
209Rappture::Pager $win.pager
210pack $win.pager -expand yes -fill both
211
212#
213# Add a place for about/questions in the breadcrumbs area of this pager.
214#
215set app [$tool xml get tool.id]
216set url [Rappture::Tool::resources -huburl]
217if {"" != $url && "" != $app} {
218    set f [$win.pager component breadcrumbarea]
219    frame $f.hubcntls
220    pack $f.hubcntls -side right -padx 4
221    label $f.hubcntls.icon -image [Rappture::icon ask] -highlightthickness 0
222    pack $f.hubcntls.icon -side left
223    button $f.hubcntls.about -text "About this tool" \
224        -command [list Rappture::filexfer::webpage "$url/tools/$app"]
225    pack $f.hubcntls.about -side top -anchor w
226    button $f.hubcntls.questions -text Questions? \
227        -command [list Rappture::filexfer::webpage "$url/resources/$app/questions"]
228    pack $f.hubcntls.questions -side top -anchor w
229}
230
231#
232# Load up the components in the various phases of input.
233#
234set phases [$tool xml children -type phase input]
235if {[llength $phases] > 0} {
236    set plist ""
237    foreach name $phases {
238        lappend plist input.$name
239    }
240    set phases $plist
241} else {
242    set phases input
243}
244
245foreach comp $phases {
246    set title [$tool xml get $comp.about.label]
247    if {$title == ""} {
248        set title "Input #auto"
249    }
250    $win.pager insert end -name $comp -title $title
251
252    #
253    # Build the page of input controls for this phase.
254    #
255    set f [$win.pager page $comp]
256    Rappture::Page $f.cntls $tool $comp
257    pack $f.cntls -expand yes -fill both
258}
259
260# let components (loaders) in the newly created pages settle
261update
262
263# ----------------------------------------------------------------------
264# OUTPUT AREA
265# ----------------------------------------------------------------------
266
267# adjust the title of the page here.
268# to adjust the button text, look in analyzer.tcl
269set simtxt [$xmlobj get tool.action.label]
270if {"" == $simtxt} {
271    set simtxt "Simulate"
272}
273$win.pager insert end -name analyzer -title $simtxt
274set f [$win.pager page analyzer]
275$win.pager page analyzer -command [subst {
276    if { !$params(-nosim) } {
277        $win.pager busy yes
278        update
279        $f.analyze simulate -ifneeded
280        $win.pager busy no
281    }
282}]
283
284Rappture::Analyzer $f.analyze $tool -simcontrol auto -notebookpage about
285pack $f.analyze -expand yes -fill both
286
287$tool notify add analyzer * [list $f.analyze reset]
288
289# ----------------------------------------------------------------------
290# Finalize the arrangement
291# ----------------------------------------------------------------------
292if {[llength [$win.pager page]] > 2} {
293    # We have phases, so we shouldn't allow the "Simulate" button.
294    # If it pops up, there are two ways to push simulate and duplicate
295    # links for "About" and "Questions?".
296    $f.analyze configure -simcontrol off
297} elseif {[llength [$win.pager page]] == 2} {
298    set style [$xmlobj get tool.layout]
299    set screenw [winfo screenwidth .]
300
301    update idletasks
302    set w0 [winfo reqwidth [$win.pager page @0]]
303    set w1 [winfo reqwidth [$win.pager page @1]]
304
305    if { $style != "wizard" } {
306        # If only two windows and they're small enough, put them up
307        # side-by-side
308        if {$w0+$w1 < $screenw } {
309            $win.pager configure -arrangement side-by-side
310            $f.analyze configure -holdwindow [$win.pager page @0]
311        }
312    }
313    set type [$tool xml get tool.control]
314    if {$type == ""} {
315        set type [$tool xml get tool.control.type]
316    }
317    set arrangement [$win.pager cget -arrangement]
318    if { $type == "" } {
319        if { $arrangement != "side-by-side" } {
320           set type auto
321        }
322    }
323    if { $arrangement != "side-by-side" &&
324            ($type == "manual" || $type == "manual-resim" ||
325             $type == "auto" || $style == "wizard") } {
326        # in "auto" mode, we don't need a simulate button
327        $f.analyze configure -simcontrol off
328    } else {
329        # not in "auto" mode but side-by-side, we always need the button
330        $f.analyze configure -simcontrol on
331    }
332}
333
334# load previous xml runfiles
335if {0 != [llength $params(-load)]} {
336    foreach runobj $loadobjs {
337        # this doesn't seem to work with loaders
338        # loaders seem to get their value after this point
339        # may need to tell loader elements to update its value
340        $tool load $runobj
341        $f.analyze load $runobj
342    }
343    # don't need simulate button if we cannot simulate
344    if {$params(-nosim)} {
345        $f.analyze configure -simcontrol off
346    }
347    $f.analyze configure -notebookpage analyze
348    $win.pager current analyzer
349}
350
351wm deiconify .main
Note: See TracBrowser for help on using the repository browser.