source: trunk/gui/scripts/xyprint.tcl @ 4745

Last change on this file since 4745 was 4181, checked in by gah, 10 years ago

add loader label to be diffed, execout(error) may not exist is no stderr

File size: 53.3 KB
Line 
1# -*- mode: tcl; indent-tabs-mode: nil -*-
2
3# ----------------------------------------------------------------------
4#  COMPONENT: xyprint - Print X-Y plot.
5#
6# ======================================================================
7#  AUTHOR:  Michael McLennan, Purdue University
8#  Copyright (c) 2004-2012  HUBzero Foundation, LLC
9#
10#  See the file "license.terms" for information on usage and
11#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12# ======================================================================
13package require Itk
14package require BLT
15
16#option add *XyPrint.width 3i widgetDefault
17#option add *XyPrint.height 3i widgetDefault
18option add *XyPrint.gridColor #d9d9d9 widgetDefault
19option add *XyPrint.activeColor blue widgetDefault
20option add *XyPrint.dimColor gray widgetDefault
21option add *XyPrint.controlBackground gray widgetDefault
22option add *XyPrint*Font "Arial 9" widgetDefault
23option add *XyPrint*Entry*width "6" widgetDefault
24option add *XyPrint*Entry*background "white" widgetDefault
25
26itcl::class Rappture::XyPrint {
27    inherit itk::Widget
28
29    constructor {args} {}
30    destructor {}
31
32    private variable _graph "";         # Original graph.
33    private variable _clone "";         # Cloned graph.
34    private variable _preview "";       # Preview image.
35    private variable _savedSettings;    # Array of settings.
36
37    private common _oldSettingsFile "~/.rpsettings"
38    private common _settingsFile "~/.rp_settings"
39
40    public method print { graph toolName plotName }
41    public method reset {}
42
43    private method CopyOptions { cmd orig clone {exclude {}}}
44    private method CloneGraph { orig }
45
46    private method BuildGeneralTab {}
47    private method BuildLayoutTab {}
48    private method BuildLegendTab {}
49    private method BuildAxisTab {}
50    private method SetOption { opt }
51    private method SetComponentOption { comp opt }
52    private method SetNamedComponentOption { comp name opt }
53    private method GetAxis {}
54    private method GetElement { args }
55    private method RegeneratePreview {}
56    private method InitClone {}
57    private method Pixels2Inches { pixels }
58    private method Inches2Pixels { inches {defValue ""}}
59    private method Color2RGB { color }
60
61    private method ApplyGeneralSettings {}
62    private method ApplyLegendSettings {}
63    private method ApplyAxisSettings {}
64    private method ApplyElementSettings {}
65    private method ApplyLayoutSettings {}
66    private method InitializeSettings {}
67    private method CreateSettings { toolName plotName }
68    private method RestoreSettings { toolName plotName }
69    private method SaveSettings { toolName plotName }
70    private method DestroySettings {}
71    private method ResetSettings { }
72    private method GetOutput {}
73    private method SetWaitVariable { state }
74    private method SetLayoutOption { option }
75    private method GetAxisType { axis }
76    private method restore { toolName plotName data }
77
78    # Same dialog may be used for different graphs
79    private common _settings
80    private common _wait
81}
82
83# ----------------------------------------------------------------------
84# CONSTRUCTOR
85# ----------------------------------------------------------------------
86itcl::body Rappture::XyPrint::constructor { args } {
87    Rappture::dispatcher _dispatcher
88    $_dispatcher register !rebuild
89    $_dispatcher dispatch $this !rebuild "[itcl::code $this Rebuild]; list"
90   
91    set w [winfo pixels . 2.5i]
92    set h [winfo pixels . 2i]
93    set _preview [image create photo -width $w -height $h]
94    itk_component add tabs {
95        blt::tabset $itk_interior.tabs \
96            -highlightthickness 0 -tearoff 0 -side top \
97            -bd 0 -gap 0 -tabborderwidth 1 \
98            -outerpad 1 -background grey
99    } {
100        keep -cursor
101        ignore -highlightthickness -borderwidth -background
102    }
103    set inner [frame $itk_interior.frame -bg grey]
104    itk_component add preview {
105        label $inner.preview \
106            -highlightthickness 0 -bd 0 -image $_preview -width 2.5i \
107                -height 2.5i -background grey
108    } {
109        ignore -background
110    }
111    itk_component add ok {
112        button $itk_interior.ok -text "Save" \
113            -highlightthickness 0 -pady 2 -padx 0 \
114            -command [itcl::code $this SetWaitVariable 1] \
115            -compound left \
116            -image [Rappture::icon download]
117    }
118    itk_component add cancel {
119        button $itk_interior.cancel -text "Cancel" \
120            -highlightthickness 0 -pady 2 -padx 0 \
121            -command [itcl::code $this SetWaitVariable 0] \
122            -compound left \
123            -image [Rappture::icon cancel]
124    }
125    blt::table $itk_interior \
126        0,0 $inner -fill both \
127        0,1 $itk_component(tabs) -fill both -cspan 2 \
128        1,2 $itk_component(cancel) -padx 2 -pady 2 -width .9i -fill y \
129        1,1 $itk_component(ok) -padx 2 -pady 2 -width .9i -fill y
130    blt::table $inner \
131        0,0 $itk_component(preview) -fill both -padx 10 -pady 10
132
133    #blt::table configure $itk_interior c1 c2 -resize none
134    blt::table configure $itk_interior c0 -resize both
135    BuildGeneralTab
136    BuildAxisTab
137    BuildLegendTab
138    BuildLayoutTab
139    eval itk_initialize $args
140}
141
142# ----------------------------------------------------------------------
143# DESTRUCTOR
144# ----------------------------------------------------------------------
145itcl::body Rappture::XyPrint::destructor {} {
146    destroy $_clone
147    image delete $_preview
148    array unset _settings $this-*
149}
150
151itcl::body Rappture::XyPrint::DestroySettings {} {
152    destroy $_clone
153    set _clone ""
154    set _graph ""
155}
156
157itcl::body Rappture::XyPrint::reset {} {
158    SetWaitVariable 0
159}
160
161itcl::body Rappture::XyPrint::SetWaitVariable { state } {
162    set _wait($this) $state
163}
164
165itcl::body Rappture::XyPrint::print { graph toolName plotName } {
166    set _graph $graph
167    CloneGraph $graph
168    InitClone
169    RestoreSettings $toolName $plotName
170    InitializeSettings
171    SetWaitVariable 0
172    tkwait variable [itcl::scope _wait($this)]
173    SaveSettings $toolName $plotName
174    set output ""
175    if { $_wait($this) } {
176        set output [GetOutput]
177    }
178    DestroySettings
179    return $output
180}
181
182itcl::body Rappture::XyPrint::GetOutput {} {
183    # Get the selected format of the download.
184    set page $itk_component(graph_page)
185    set format [$page.format current]
186
187    if { $format == "jpg" } {
188        set img [image create photo]
189        $_clone snap $img
190        set bytes [$img data -format "jpeg -quality 100"]
191        set bytes [Rappture::encoding::decode -as b64 $bytes]
192        image delete $img
193        return [list .jpg $bytes]
194    } elseif { $format == "png" } {
195        set img [image create photo]
196        $_clone snap $img
197        set bytes [$img data -format "png"]
198        set bytes [Rappture::encoding::decode -as b64 $bytes]
199        image delete $img
200        return [list .png $bytes]
201    }
202
203    # Handle encapsulated postscript or portable document format.
204
205    # Append an "i" for the graph postscript component.
206    set w $_settings($this-layout-width)i
207    set h $_settings($this-layout-height)i
208
209    $_clone postscript configure \
210        -maxpect false \
211        -decoration yes \
212        -center yes \
213        -width $w -height $h
214   
215    set psdata [$_clone postscript output]
216
217    if 0 {
218        set f [open "junk.raw" "w"]
219        puts -nonewline $f $psdata
220        close $f
221    }
222    if { $format == "eps" } {
223        return [list .$format $psdata]
224    }
225
226    set cmd ""
227    # | eps2eps << $psdata
228    lappend cmd "|" "/usr/bin/gs" \
229        "-q" "-sDEVICE=epswrite" "-sstdout=%stderr" \
230        "-sOutputFile=-" "-dNOPAUSE" "-dBATCH" "-dSAFER" \
231        "-dDEVICEWIDTH=250000" "-dDEVICEHEIGHT=250000" "-" "<<" "$psdata"
232    if { $format == "pdf" } {
233        # | eps2eps << $psdata | ps2pdf
234        lappend cmd "|" "/usr/bin/gs" \
235            "-q" "-sDEVICE=pdfwrite" "-sstdout=%stderr" \
236            "-sOutputFile=-" "-dNOPAUSE" "-dBATCH" "-dSAFER" \
237            "-dCompatibilityLevel=1.4" "-c" ".setpdfwrite" "-f" "-"
238    }
239    if { [catch {
240        set f [open $cmd "r"]
241        fconfigure $f -translation binary -encoding binary
242        set output [read $f]
243        close $f
244    } err ] != 0 } {
245        global errorInfo
246        puts stderr "failed to generate file: $err\n$errorInfo"
247        return ""
248    }
249    if 0 {
250        set f [open "junk.$format" "w"]
251        fconfigure $f -translation binary -encoding binary
252        puts -nonewline $f $output
253        close $f
254    }
255    return [list .$format $output]
256}
257
258itcl::body Rappture::XyPrint::CopyOptions { cmd orig clone {exclude {}} } {
259    set all [eval $orig $cmd]
260    set configLine $clone
261    foreach name $exclude {
262        set ignore($name) 1
263    }
264    foreach arg $cmd {
265        lappend configLine $arg
266    }
267    foreach option $all {
268        if { [llength $option] != 5 } {
269            continue
270        }
271        set switch [lindex $option 0]
272        set initial [lindex $option 3]
273        set current [lindex $option 4]
274        if { [info exists ignore($switch)] } {
275            continue
276        }
277        if { [string compare $initial $current] == 0 } {
278            continue
279        }
280        lappend configLine $switch $current
281    }
282    eval $configLine
283}
284
285itcl::body Rappture::XyPrint::CloneGraph { orig } {
286    set top $itk_interior
287    if { [winfo exists $top.graph] } {
288        destroy $top.graph
289    }
290    set _clone [blt::graph $top.graph]
291    CopyOptions "configure" $orig $_clone
292    # Axis component
293    foreach axis [$orig axis names] {
294        if { $axis == "z" } {
295            continue
296        }
297        if { [$orig axis cget $axis -hide] } {
298            continue
299        }
300        if { [$_clone axis name $axis] == "" } {
301            $_clone axis create $axis
302        }
303        CopyOptions [list axis configure $axis] $orig $_clone
304    }
305    foreach axis { x y x2 y2 } {
306        $_clone ${axis}axis use [$orig ${axis}axis use]
307    }
308    # Pen component
309    foreach pen [$orig pen names] {
310        if { [$_clone pen name $pen] == "" } {
311            $_clone pen create $pen
312        }
313        CopyOptions [list pen configure $pen] $orig $_clone
314    }
315    # Marker component
316    foreach marker [$orig marker names] {
317        $_clone marker create [$orig marker type $marker] -name $marker
318        CopyOptions [list marker configure $marker] $orig $_clone -name
319    }
320    # Element component
321    foreach elem [$orig element names] {
322        set oper [$orig element type $elem]
323        $_clone $oper create $elem
324        CopyOptions [list $oper configure $elem] $orig $_clone -data
325        if { [$_clone $oper cget $elem -hide] } {
326            $_clone $oper configure $elem -label ""
327        }
328    }
329    # Fix element display list
330    $_clone element show [$orig element show]
331    # Legend component
332    CopyOptions {legend configure} $orig $_clone
333    # Postscript component
334    CopyOptions {postscript configure} $orig $_clone
335    # Crosshairs component
336    CopyOptions {crosshairs configure} $orig $_clone
337    # Grid component
338    CopyOptions {grid configure} $orig $_clone
339
340    # Create markers representing lines at zero for the x and y axis.
341    $_clone marker create line -name x-zero \
342        -coords "0 -Inf 0 Inf" -dashes 1 -hide yes
343    $_clone marker create line -name y-zero \
344        -coords "-Inf 0 Inf 0" -dashes 1 -hide yes
345}
346
347itcl::body Rappture::XyPrint::InitClone {} {
348   
349    $_clone configure -width 3.4i -height 3.4i -background white \
350        -borderwidth 0 \
351        -leftmargin 0 \
352        -rightmargin 0 \
353        -topmargin 0 \
354        -bottommargin 0
355   
356    # Kill the title and create a border around the plot
357    $_clone configure \
358        -title "" \
359        -plotborderwidth 1 -plotrelief solid  \
360        -plotbackground white -plotpadx 0 -plotpady 0
361
362    set _settings($this-layout-width) [Pixels2Inches [$_clone cget -width]]
363    set _settings($this-layout-height) [Pixels2Inches [$_clone cget -height]]
364
365    set _settings($this-legend-fontfamily) helvetica
366    set _settings($this-legend-fontsize)   10
367    set _settings($this-legend-fontweight) normal
368    set _settings($this-legend-fontslant)  roman
369    set font "helvetica 10 normal roman"
370    $_clone legend configure \
371        -position right \
372        -font $font \
373        -hide yes -borderwidth 0 -background white -relief solid \
374        -anchor nw -activeborderwidth 0
375    #
376    set _settings($this-axis-ticks-fontfamily) helvetica
377    set _settings($this-axis-ticks-fontsize)   10
378    set _settings($this-axis-ticks-fontweight) normal
379    set _settings($this-axis-ticks-fontslant)  roman
380    set _settings($this-axis-title-fontfamily) helvetica
381    set _settings($this-axis-title-fontsize)   10
382    set _settings($this-axis-title-fontweight) normal
383    set _settings($this-axis-title-fontslant)  roman
384    foreach axis [$_clone axis names] {
385        if { $axis == "z" } {
386            continue
387        }
388        if { [$_clone axis cget $axis -hide] } {
389            continue
390        }
391        set _settings($this-$axis-ticks-fontfamily) helvetica
392        set _settings($this-$axis-ticks-fontsize)   10
393        set _settings($this-$axis-ticks-fontweight) normal
394        set _settings($this-$axis-ticks-fontslant)  roman
395        set _settings($this-$axis-title-fontfamily) helvetica
396        set _settings($this-$axis-title-fontsize)   10
397        set _settings($this-$axis-title-fontweight) normal
398        set _settings($this-$axis-title-fontslant)  roman
399        set tickfont "helvetica 10 normal roman"
400        set titlefont "helvetica 10 normal roman"
401        $_clone axis configure $axis -ticklength 5  \
402            -majorticks {} -minorticks {}
403        $_clone axis configure $axis \
404            -tickfont $tickfont \
405            -titlefont $titlefont
406    }
407    set count 0
408    foreach elem [$_clone element names] {
409        if { [$_clone element type $elem] == "bar" } {
410            continue
411        }
412        incr count
413        if { [$_clone element cget $elem -linewidth] > 1 } {
414            $_clone element configure $elem -linewidth 1 -pixels 3
415        }
416    }
417    if { $count == 0 } {
418        # There are no "line" elements in the graph.
419        # Remove the symbol and dashes controls.
420        set page $itk_component(legend_page)
421        # May have already been forgotten.
422        catch {
423            blt::table forget $page.symbol_l
424            blt::table forget $page.symbol
425            blt::table forget $page.dashes_l
426            blt::table forget $page.dashes
427        }
428    }
429}
430
431itcl::body Rappture::XyPrint::SetOption { opt } {
432    set new $_settings($this$opt)
433    set old [$_clone cget $opt]
434    set code [catch [list $_clone configure $opt $new] err]
435    if { $code != 0 } {
436        bell
437        global errorInfo
438        puts stderr "$err: $errorInfo"
439        set _settings($this$opt) $old
440        $_clone configure $opt $old
441    }
442}
443
444itcl::body Rappture::XyPrint::SetComponentOption { comp opt } {
445    set new $_settings($this-$comp$opt)
446    set old [$_clone $comp cget $opt]
447    set code [catch [list $_clone $comp configure $opt $new] err]
448    if { $code != 0 } {
449        bell
450        global errorInfo
451        puts stderr "$err: $errorInfo"
452        set _settings($this-$comp$opt) $old
453        $_clone $comp configure $opt $old
454    }
455}
456
457itcl::body Rappture::XyPrint::SetNamedComponentOption { comp name opt } {
458    set new $_settings($this-$comp$opt)
459    set old [$_clone $comp cget $name $opt]
460    set code [catch [list $_clone $comp configure $name $opt $new] err]
461    if { $code != 0 } {
462        bell
463        global errorInfo
464        puts stderr "$err: $errorInfo"
465        set _settings($this-$comp$opt) $old
466        $_clone $comp configure $name $opt $old
467    }
468}
469
470itcl::body Rappture::XyPrint::RegeneratePreview {} {
471    update
472    set img [image create photo]
473    set w [Inches2Pixels $_settings($this-layout-width) 3.4]
474    set h [Inches2Pixels $_settings($this-layout-height) 3.4]
475    $_clone snap $img -width $w -height $h
476
477    set pixelsPerInch [winfo pixels . 1i]
478    set cw [winfo width $itk_component(preview)]
479    set ch [winfo height $itk_component(preview)]
480    set rw [expr 2.5*$pixelsPerInch]
481    set rh [expr 2.5*$pixelsPerInch]
482    set maxwidth $rw
483    set maxheight $rh
484    if { $maxwidth > $cw } {
485        set maxwidth $cw
486    }
487    if { $maxheight > $ch } {
488        set maxheight $ch
489    }
490    set sx [expr double($maxwidth)/$w]
491    set sy [expr double($maxheight)/$h]
492    set s [expr min($sx,$sy)]
493
494    set pw [expr int(round($s * $w))]
495    set ph [expr int(round($s * $h))]
496    $_preview configure -width $pw -height $ph
497    blt::winop resample $img $_preview box
498    image delete $img
499}
500
501itcl::body Rappture::XyPrint::Pixels2Inches { pixels } {
502    if { [llength $pixels] == 2 } {
503        set pixels [lindex $pixels 0]
504    }
505    set pixelsPerInch [winfo pixels . 1i]
506    set inches [expr { double($pixels) / $pixelsPerInch }]
507    return [format %.3g ${inches}]
508}
509
510itcl::body Rappture::XyPrint::Inches2Pixels { inches {defValue ""}} {
511    set n [scan $inches %g dummy]
512    if { $n != 1  && $defValue != "" } {
513        set inches $defValue
514    }
515    return  [winfo pixels . ${inches}i]
516}
517
518itcl::body Rappture::XyPrint::Color2RGB { color } {
519    foreach { r g b } [winfo rgb $_clone $color] {
520        set r [expr round($r / 257.0)]
521        set g [expr round($g / 257.0)]
522        set b [expr round($b / 257.0)]
523    }
524    return [format "\#%02x%02x%02x" $r $g $b]
525}
526
527itcl::body Rappture::XyPrint::GetAxisType { axis } {
528    foreach type { x y x2 y2 } {
529        set axes [$_clone ${type}axis use]
530        if { [lsearch $axes $axis] >= 0 } {
531            return [string range $type 0 0]
532        }
533    }
534    return ""
535}
536
537itcl::body Rappture::XyPrint::GetAxis {} {
538    set axis [$itk_component(axis_combo) current]
539    foreach option { -min -max -loose -title -stepsize -subdivisions } {
540        set _settings($this-axis$option) [$_clone axis cget $axis $option]
541    }
542    foreach attr { fontfamily fontsize fontweight fontslant } {
543        set specific $this-$axis-ticks
544        set general $this-axis-ticks
545        set _settings(${general}-${attr}) $_settings(${specific}-${attr})
546        set specific $this-$axis-title
547        set general $this-axis-title
548        set _settings(${general}-${attr}) $_settings(${specific}-${attr})
549    }
550    set type [GetAxisType $axis]
551    if { [$_clone grid cget -map${type}] == $axis } {
552        set _settings($this-axis-grid) 1
553    }  else {
554        set _settings($this-axis-grid) 0
555    }
556    set _settings($this-axis-plotpad${type}) \
557        [Pixels2Inches [$_clone cget -plotpad${type}]]
558    set _settings($this-axis-zero) [$_clone marker cget ${type}-zero -hide]
559}
560
561itcl::body Rappture::XyPrint::GetElement { args } {
562    set index 1
563    array unset _settings $this-element-*
564    foreach elem [$_clone element show] {
565        set _settings($this-element-$index) $elem
566        incr index
567    }
568    set index [$itk_component(element_slider) get]
569    set elem $_settings($this-element-$index)
570    set _settings($this-element-label) [$_clone element cget $elem -label]
571    set _settings($this-element-color) [$_clone element cget $elem -color]
572    if { [$_clone element type $elem] != "bar" } {
573        set _settings($this-element-symbol) [$_clone element cget $elem -symbol]
574        set _settings($this-element-dashes) [$_clone element cget $elem -dashes]
575    }
576    set page $itk_component(legend_page)
577    set color [$page.color label $_settings($this-element-color)]
578    if { $color == "" } {
579        set color [Color2RGB $_settings($this-element-color)]
580        $page.color choices insert end $color $color
581        $page.color value $color
582    } else {
583        $page.color value [$page.color label $_settings($this-element-color)]
584    }
585    if { [$_clone element type $elem] != "bar" } {
586        $page.symbol value [$page.symbol label $_settings($this-element-symbol)]
587        $page.dashes value [$page.dashes label $_settings($this-element-dashes)]
588    }
589    #FixElement
590}
591
592itcl::body Rappture::XyPrint::BuildLayoutTab {} {
593    itk_component add layout_page {
594        frame $itk_component(tabs).layout_page
595    }
596    set page $itk_component(layout_page)
597    $itk_component(tabs) insert end "layout" \
598        -text "Layout" -padx 2 -pady 2 -window $page -fill both
599
600    label $page.width_l -text "width" 
601    entry $page.width -width 6 \
602        -textvariable [itcl::scope _settings($this-layout-width)]
603    bind  $page.width <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
604    Rappture::Tooltip::for $page.width \
605        "Set the width (inches) of the output image. Must be a positive number."
606
607    label $page.height_l -text "height"
608    entry $page.height -width 6 \
609        -textvariable [itcl::scope _settings($this-layout-height)]
610    bind  $page.height <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
611    Rappture::Tooltip::for $page.height \
612        "Set the height (inches) of the output image. Must be a positive number"
613
614    label $page.margin_l -text "Margins" 
615
616    label $page.left_l -text "left"
617    entry $page.left -width 6 \
618        -textvariable [itcl::scope _settings($this-layout-leftmargin)]
619    bind  $page.left <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
620    Rappture::Tooltip::for $page.left \
621        "Set the size (inches) of the left margin. If zero, the size is automatically determined."
622
623    label $page.right_l -text "right"
624    entry $page.right -width 6 \
625        -textvariable [itcl::scope _settings($this-layout-rightmargin)]
626    bind  $page.right <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
627    Rappture::Tooltip::for $page.right \
628        "Set the size (inches) of the right margin. If zero, the size is automatically determined."
629
630
631    label $page.top_l -text "top"
632    entry $page.top -width 6 \
633        -textvariable [itcl::scope _settings($this-layout-topmargin)]
634    bind  $page.top <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
635    Rappture::Tooltip::for $page.top \
636        "Set the size (inches) of the top margin. If zero, the size is automatically determined."
637
638    label $page.bottom_l -text "bottom"
639    entry $page.bottom -width 6 \
640        -textvariable [itcl::scope _settings($this-layout-bottommargin)]
641    bind  $page.bottom <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
642    Rappture::Tooltip::for $page.bottom \
643        "Set the size (inches) of the bottom margin. If zero, the size is automatically determined."
644
645
646    label $page.map -image [Rappture::icon graphmargins]
647    blt::table $page \
648        0,0 $page.width_l -anchor e \
649        0,1 $page.width -fill x  \
650        1,0 $page.height_l -anchor e \
651        1,1 $page.height -fill x \
652        3,0 $page.left_l -anchor e \
653        3,1 $page.left -fill x  \
654        4,0 $page.right_l -anchor e \
655        4,1 $page.right -fill x \
656        5,0 $page.top_l -anchor e \
657        5,1 $page.top -fill x \
658        6,0 $page.bottom_l -anchor e \
659        6,1 $page.bottom -fill x  \
660        0,2 $page.map -fill both -rspan 7 -padx 2
661
662    blt::table configure $page c0 r* -resize none
663    blt::table configure $page c1 r2 -resize both
664}
665
666
667itcl::body Rappture::XyPrint::BuildGeneralTab {} {
668    itk_component add graph_page {
669        frame $itk_component(tabs).graph_page
670    }
671    set page $itk_component(graph_page)
672    $itk_component(tabs) insert end "graph" \
673        -text "General" -padx 2 -pady 2 -window $page -fill both
674
675    label $page.format_l -text "format"
676    Rappture::Combobox $page.format -width 30 -editable no
677    $page.format choices insert end \
678        "pdf" "PDF Portable Document Format" \
679        "ps"  "PS PostScript Format"  \
680        "eps" "EPS Encapsulated PostScript"  \
681        "jpg" "JPEG Joint Photographic Experts Group Format" \
682        "png" "PNG Portable Network Graphics Format"         
683
684    bind $page.format <<Value>> [itcl::code $this ApplyGeneralSettings]
685    Rappture::Tooltip::for $page.format \
686        "Set the format of the image."
687
688    label $page.style_l -text "style"
689    Rappture::Combobox $page.style -width 20 -editable no
690    $page.style choices insert end \
691        "ieee" "IEEE Journal"  \
692        "gekco" "G Klimeck" 
693    bind $page.style <<Value>> [itcl::code $this ApplyGeneralSettings]
694    Rappture::Tooltip::for $page.format \
695        "Set the style template."
696
697    checkbutton $page.remember -text "remember settings" \
698        -variable [itcl::scope _settings($this-general-remember)] 
699    Rappture::Tooltip::for $page.remember \
700        "Remember the settings. They will be override the default settings."
701
702    button $page.revert -text "revert" -image [Rappture::icon revert] \
703        -compound left -padx 3 -pady 1 -overrelief raised -relief flat \
704        -command [itcl::code $this ResetSettings]
705    Rappture::Tooltip::for $page.revert \
706        "Revert to the default settings."
707
708    blt::table $page \
709        2,0 $page.format_l -anchor e \
710        2,1 $page.format -fill x -cspan 2 \
711        3,0 $page.style_l -anchor e \
712        3,1 $page.style -fill x -cspan 2 \
713        5,0 $page.remember -cspan 2 -anchor w \
714        5,2 $page.revert -anchor e
715    blt::table configure $page r* -resize none  -pady { 0 2 }
716    blt::table configure $page r4 -resize both
717
718}
719   
720itcl::body Rappture::XyPrint::ApplyLegendSettings {} {
721    set page $itk_component(legend_page)
722    set _settings($this-legend-anchor)    [$page.anchor current]
723    if { $_clone != "" } {
724        lappend font $_settings($this-legend-fontfamily)
725        lappend font $_settings($this-legend-fontsize)
726        lappend font $_settings($this-legend-fontweight)
727        lappend font $_settings($this-legend-fontslant)
728        foreach option { -hide -position -anchor -borderwidth } {
729            SetComponentOption legend $option
730        }
731        $_clone legend configure -font fixed -font $font
732    }
733    ApplyElementSettings
734}
735
736itcl::body Rappture::XyPrint::BuildLegendTab {} {
737    itk_component add legend_page {
738        frame $itk_component(tabs).legend_page
739    }
740    set page $itk_component(legend_page)
741    $itk_component(tabs) insert end "legend" \
742        -text "Legend" -padx 2 -pady 2 -window $page -fill both
743
744    checkbutton $page.show -text "show legend" \
745        -offvalue 1 -onvalue 0 \
746        -variable [itcl::scope _settings($this-legend-hide)]  \
747        -command [itcl::code $this ApplyLegendSettings]
748    Rappture::Tooltip::for $page.show \
749        "Display the legend."
750
751    label $page.position_l -text "position"
752    Rappture::Combobox $page.position -width 15 -editable no
753    $page.position choices insert end \
754        "leftmargin" "left margin"  \
755        "rightmargin" "right margin"  \
756        "bottommargin" "bottom margin"  \
757        "topmargin" "top margin"  \
758        "plotarea" "inside plot"
759    bind $page.position <<Value>> [itcl::code $this ApplyLegendSettings]
760    Rappture::Tooltip::for $page.position \
761        "Set the position of the legend.  This option and the anchor determine the legend's location."
762
763    Rappture::Combobox $page.anchor -width 10 -editable no
764    $page.anchor choices insert end \
765        "nw" "northwest"  \
766        "n" "north"  \
767        "ne" "northeast"  \
768        "sw" "southwest"  \
769        "s" "south"  \
770        "se" "southeast"  \
771        "c" "center"  \
772        "e" "east"  \
773        "w" "west" 
774    bind $page.anchor <<Value>> [itcl::code $this ApplyLegendSettings]
775    Rappture::Tooltip::for $page.anchor \
776        "Set the anchor of the legend.  This option and the anchor determine the legend's location."
777
778    checkbutton $page.border -text "border" \
779        -variable [itcl::scope _settings($this-legend-borderwidth)] \
780        -onvalue 1 -offvalue 0 \
781        -command [itcl::code $this ApplyLegendSettings]
782    Rappture::Tooltip::for $page.border \
783        "Display a solid border around the legend."
784
785    label $page.slider_l -text "legend\nentry"  -justify right
786    itk_component add element_slider {
787        ::scale $page.slider -from 1 -to 1 \
788            -orient horizontal -width 12 \
789            -command [itcl::code $this GetElement]
790    }
791    Rappture::Tooltip::for $page.slider \
792        "Select the current entry."
793
794    label $page.label_l -text "label"
795    entry $page.label \
796        -background white \
797        -textvariable [itcl::scope _settings($this-element-label)]
798    bind  $page.label <KeyPress-Return> [itcl::code $this ApplyElementSettings]
799    Rappture::Tooltip::for $page.label \
800        "Set the label of the current entry in the legend."
801
802    label $page.color_l -text "color "
803    Rappture::Combobox $page.color -width 15 -editable no
804    $page.color choices insert end \
805        "#000000" "black" \
806        "#ffffff" "white" \
807        "#0000cd" "blue" \
808        "#cd0000" "red" \
809        "#00cd00" "green" \
810        "#3a5fcd" "royal blue" \
811        "#cdcd00" "yellow" \
812        "#cd1076" "deep pink" \
813        "#009acd" "deep sky blue" \
814        "#00c5cd" "torquise" \
815        "#a2b5cd" "light steel blue" \
816        "#7ac5cd" "cadet blue" \
817        "#66cdaa" "aquamarine" \
818        "#a2cd5a" "dark olive green" \
819        "#cd9b9b" "rosy brown" \
820        "#0000ff" "blue1" \
821        "#ff0000" "red1" \
822        "#00ff00" "green1"
823    bind $page.color <<Value>> [itcl::code $this ApplyElementSettings]
824    Rappture::Tooltip::for $page.color \
825        "Set the color of the current entry."
826
827    label $page.dashes_l -text "line style"
828    Rappture::Combobox $page.dashes -width 15 -editable no
829    $page.dashes choices insert end \
830        "" "solid"  \
831        "1" "dot" \
832        "5 2" "dash" \
833        "2 4 2" "dashdot" \
834        "2 4 2 2" "dashdotdot"
835    bind $page.dashes <<Value>> [itcl::code $this ApplyElementSettings]
836    Rappture::Tooltip::for $page.dashes \
837        "Set the line style of the current entry."
838
839    label $page.symbol_l -text "symbol"
840    Rappture::Combobox $page.symbol -editable no
841    $page.symbol choices insert end \
842        "none" "none"  \
843        "square" "square" \
844        "circle" "circle" \
845        "diamond" "diamond" \
846        "plus" "plus" \
847        "cross" "cross" \
848        "splus" "skinny plus"  \
849        "scross" "skinny cross" \
850        "triangle" "triangle"
851    bind $page.symbol <<Value>> [itcl::code $this ApplyElementSettings]
852    Rappture::Tooltip::for $page.symbol \
853        "Set the symbol of the current entry. \"none\" display no symbols."
854
855    label $page.font_l -text "font"
856    Rappture::Combobox $page.fontfamily -width 10 -editable no
857    $page.fontfamily choices insert end \
858        "courier" "courier" \
859        "helvetica" "helvetica"  \
860        "new*century*schoolbook"  "new century schoolbook" \
861        "symbol"  "symbol" \
862        "times"  "times"         
863    bind $page.fontfamily <<Value>> [itcl::code $this ApplyLegendSettings]
864    Rappture::Tooltip::for $page.fontfamily \
865        "Set the font of entries in the legend."
866
867    Rappture::Combobox $page.fontsize -width 4 -editable no
868    $page.fontsize choices insert end \
869        "8" "8" \
870        "9" "9" \
871        "10" "10" \
872        "11" "11" \
873        "12" "12" \
874        "14" "14" \
875        "17" "17" \
876        "18" "18" \
877        "20" "20"
878    bind  $page.fontsize <<Value>> [itcl::code $this ApplyLegendSettings]
879    Rappture::Tooltip::for $page.fontsize \
880        "Set the size (points) of the font."
881
882    Rappture::PushButton $page.fontweight \
883        -onimage [Rappture::icon font-bold] \
884        -offimage [Rappture::icon font-bold] \
885        -onvalue "bold" -offvalue "normal" \
886        -command [itcl::code $this ApplyLegendSettings] \
887        -variable [itcl::scope _settings($this-legend-fontweight)]
888    Rappture::Tooltip::for $page.fontweight \
889        "Use the bold version of the font."
890
891    Rappture::PushButton $page.fontslant \
892        -onimage [Rappture::icon font-italic] \
893        -offimage [Rappture::icon font-italic] \
894        -onvalue "italic" -offvalue "roman" \
895        -command [itcl::code $this ApplyLegendSettings] \
896        -variable [itcl::scope _settings($this-legend-fontslant)]
897    Rappture::Tooltip::for $page.fontslant \
898        "Use the italic version of the font."
899
900    blt::table $page \
901        1,0 $page.show -cspan 2 -anchor w \
902        1,2 $page.border -cspan 2 -anchor w \
903        2,0 $page.position_l -anchor e \
904        2,1 $page.position -fill x \
905        2,2 $page.anchor -fill x  -cspan 3 \
906        3,0 $page.font_l -anchor e \
907        3,1 $page.fontfamily -fill x \
908        3,2 $page.fontsize -fill x \
909        3,3 $page.fontweight -anchor e \
910        3,4 $page.fontslant -anchor e \
911        4,0 $page.slider_l -anchor e \
912        4,1 $page.slider -fill x -cspan 5 \
913        5,0 $page.label_l -anchor e \
914        5,1 $page.label -fill x -cspan 5 \
915        6,0 $page.color_l -anchor e \
916        6,1 $page.color -fill x \
917        6,2 $page.symbol_l -anchor e \
918        6,3 $page.symbol -fill both -cspan 3 \
919        7,0 $page.dashes_l -anchor e \
920        7,1 $page.dashes -fill x \
921
922    blt::table configure $page r* -resize none -pady { 0 2 }
923    blt::table configure $page c3 c4 -resize none
924    blt::table configure $page r8 -resize both
925
926}
927
928itcl::body Rappture::XyPrint::BuildAxisTab {} {
929    itk_component add axis_page {
930        frame $itk_component(tabs).axis_page
931    }
932    set page $itk_component(axis_page)
933    $itk_component(tabs) insert end "axis" \
934        -text "Axis" -padx 2 -pady 2 -window $page -fill both
935   
936    label $page.axis_l -text "axis"
937    itk_component add axis_combo {
938        Rappture::Combobox $page.axis -width 20 -editable no
939    }
940    bind $itk_component(axis_combo) <<Value>> [itcl::code $this GetAxis]
941    Rappture::Tooltip::for $page.axis \
942        "Select the current axis."
943
944    label $page.title_l -text "title"
945    entry $page.title \
946        -textvariable [itcl::scope _settings($this-axis-title)]
947    bind  $page.title <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
948    Rappture::Tooltip::for $page.title \
949        "Set the title of the current axis."
950
951    label $page.min_l -text "min"
952    entry $page.min -width 10 \
953        -textvariable [itcl::scope _settings($this-axis-min)]
954    bind  $page.min <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
955    Rappture::Tooltip::for $page.min \
956        "Set the minimum limit for the current axis. If empty, the minimum is automatically determined."
957
958    label $page.max_l -text "max"
959    entry $page.max -width 10 \
960        -textvariable [itcl::scope _settings($this-axis-max)]
961    bind  $page.max <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
962    Rappture::Tooltip::for $page.max \
963        "Set the maximum limit for the current axis. If empty, the maximum is automatically determined."
964
965    label $page.subdivisions_l -text "subdivisions"
966    entry $page.subdivisions \
967        -textvariable [itcl::scope _settings($this-axis-subdivisions)]
968    bind  $page.subdivisions <KeyPress-Return> \
969        [itcl::code $this ApplyAxisSettings]
970    Rappture::Tooltip::for $page.subdivisions \
971        "Set the number of subdivisions (minor ticks) for the current axis."
972
973    label $page.stepsize_l -text "step size"
974    entry $page.stepsize \
975        -textvariable [itcl::scope _settings($this-axis-stepsize)]
976    bind  $page.stepsize <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
977    Rappture::Tooltip::for $page.stepsize \
978        "Set the interval between major ticks for the current axis. If zero, the interval is automatically determined."
979
980    checkbutton $page.loose -text "loose limits" \
981        -onvalue "always" -offvalue "0" \
982        -variable [itcl::scope _settings($this-axis-loose)] \
983        -command [itcl::code $this ApplyAxisSettings]
984    Rappture::Tooltip::for $page.loose \
985        "Set major ticks outside of the limits for the current axis."
986
987    label $page.plotpad_l -text "pad" 
988    entry $page.plotpad -width 6 \
989        -textvariable [itcl::scope _settings($this-axis-plotpad)]
990    bind  $page.plotpad <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
991    Rappture::Tooltip::for $page.plotpad \
992        "Set padding (points) between the current axis and the plot."
993
994    checkbutton $page.grid -text "show grid lines" \
995        -variable [itcl::scope _settings($this-axis-grid)] \
996        -command [itcl::code $this ApplyAxisSettings]
997    Rappture::Tooltip::for $page.grid \
998        "Display grid lines for the current axis."
999
1000    checkbutton $page.zero -text "mark zero" \
1001        -offvalue 1 -onvalue 0 \
1002        -variable [itcl::scope _settings($this-axis-zero)] \
1003        -command [itcl::code $this ApplyAxisSettings]
1004    Rappture::Tooltip::for $page.zero \
1005        "Display a line at zero for the current axis."
1006
1007    label $page.tickfont_l -text "tick font"
1008    Rappture::Combobox $page.tickfontfamily -width 10 -editable no
1009    $page.tickfontfamily choices insert end \
1010        "courier" "courier" \
1011        "helvetica" "helvetica"  \
1012        "new*century*schoolbook"  "new century schoolbook" \
1013        "symbol"  "symbol" \
1014        "times"  "times"         
1015    bind $page.tickfontfamily <<Value>> [itcl::code $this ApplyAxisSettings]
1016    Rappture::Tooltip::for $page.tickfontfamily \
1017        "Set the font of the ticks for the current axis."
1018
1019    Rappture::Combobox $page.tickfontsize -width 4 -editable no
1020    $page.tickfontsize choices insert end \
1021        "8" "8" \
1022        "9" "9" \
1023        "10" "10" \
1024        "11" "11" \
1025        "12" "12" \
1026        "14" "14" \
1027        "17" "17" \
1028        "18" "18" \
1029        "20" "20"
1030    bind $page.tickfontsize <<Value>> [itcl::code $this ApplyAxisSettings]
1031    Rappture::Tooltip::for $page.tickfontsize \
1032        "Set the size (points) of the tick font."
1033
1034    Rappture::PushButton $page.tickfontweight \
1035        -onimage [Rappture::icon font-bold] \
1036        -offimage [Rappture::icon font-bold] \
1037        -onvalue "bold" -offvalue "normal" \
1038        -command [itcl::code $this ApplyAxisSettings] \
1039        -variable [itcl::scope _settings($this-axis-ticks-fontweight)]
1040    Rappture::Tooltip::for $page.tickfontweight \
1041        "Use the bold version of the tick font."
1042
1043    Rappture::PushButton $page.tickfontslant \
1044        -onimage [Rappture::icon font-italic] \
1045        -offimage [Rappture::icon font-italic] \
1046        -onvalue "italic" -offvalue "roman" \
1047        -command [itcl::code $this ApplyAxisSettings] \
1048        -variable [itcl::scope _settings($this-axis-ticks-fontslant)]
1049    Rappture::Tooltip::for $page.tickfontslant \
1050        "Use the italic version of the tick font."
1051
1052    label $page.titlefont_l -text "title font"
1053    Rappture::Combobox $page.titlefontfamily -width 10 -editable no
1054    $page.titlefontfamily choices insert end \
1055        "courier" "courier" \
1056        "helvetica" "helvetica"  \
1057        "new*century*schoolbook"  "new century schoolbook" \
1058        "symbol"  "symbol" \
1059        "times"  "times"         
1060    bind $page.titlefontfamily <<Value>> [itcl::code $this ApplyAxisSettings]
1061    Rappture::Tooltip::for $page.titlefontfamily \
1062        "Set the font of the title for the current axis."
1063
1064    Rappture::Combobox $page.titlefontsize -width 4 -editable no
1065    $page.titlefontsize choices insert end \
1066        "8" "8" \
1067        "9" "9" \
1068        "10" "10" \
1069        "11" "11" \
1070        "12" "12" \
1071        "14" "14" \
1072        "17" "17" \
1073        "18" "18" \
1074        "20" "20"
1075    bind $page.titlefontsize <<Value>> [itcl::code $this ApplyAxisSettings]
1076    Rappture::Tooltip::for $page.titlefontsize \
1077        "Set the size (point) of the title font."
1078
1079    Rappture::PushButton $page.titlefontweight \
1080        -onimage [Rappture::icon font-bold] \
1081        -offimage [Rappture::icon font-bold] \
1082        -onvalue "bold" -offvalue "normal" \
1083        -command [itcl::code $this ApplyAxisSettings] \
1084        -variable [itcl::scope _settings($this-axis-title-fontweight)]
1085    Rappture::Tooltip::for $page.titlefontweight \
1086        "Use the bold version of the title font."
1087
1088    Rappture::PushButton $page.titlefontslant \
1089        -onimage [Rappture::icon font-italic] \
1090        -offimage [Rappture::icon font-italic] \
1091        -onvalue "italic" -offvalue "roman" \
1092        -command [itcl::code $this ApplyAxisSettings] \
1093        -variable [itcl::scope _settings($this-axis-title-fontslant)]
1094    Rappture::Tooltip::for $page.titlefontslant \
1095        "Use the italic version of the title font."
1096
1097    blt::table $page \
1098        1,1 $page.axis_l -anchor e  -pady 6 \
1099        1,2 $page.axis -fill x -cspan 6 \
1100        2,1 $page.title_l -anchor e \
1101        2,2 $page.title -fill x -cspan 5 \
1102        3,1 $page.min_l -anchor e \
1103        3,2 $page.min -fill x \
1104        3,3 $page.stepsize_l -anchor e \
1105        3,4 $page.stepsize -fill both -cspan 3 \
1106        4,1 $page.max_l -anchor e \
1107        4,2 $page.max -fill both \
1108        4,3 $page.subdivisions_l -anchor e \
1109        4,4 $page.subdivisions -fill both -cspan 3  \
1110        5,1 $page.titlefont_l -anchor e \
1111        5,2 $page.titlefontfamily -fill x -cspan 2 \
1112        5,4 $page.titlefontsize -fill x \
1113        5,5 $page.titlefontweight -anchor e \
1114        5,6 $page.titlefontslant -anchor e \
1115        6,1 $page.tickfont_l -anchor e \
1116        6,2 $page.tickfontfamily -fill x -cspan 2 \
1117        6,4 $page.tickfontsize -fill x \
1118        6,5 $page.tickfontweight -anchor e \
1119        6,6 $page.tickfontslant -anchor e \
1120        7,1 $page.loose -cspan 2 -anchor w \
1121        7,3 $page.grid -anchor w -cspan 2 \
1122        8,1 $page.zero -cspan 2 -anchor w \
1123        8,3 $page.plotpad_l -anchor e \
1124        8,4 $page.plotpad -fill both -cspan 3
1125
1126    blt::table configure $page  c0 c4 c5 c6 c7 c8 -resize none
1127}
1128
1129itcl::body Rappture::XyPrint::ApplyGeneralSettings {} {
1130    RegeneratePreview
1131}
1132
1133itcl::body Rappture::XyPrint::ApplyLegendSettings {} {
1134    set page $itk_component(legend_page)
1135    set _settings($this-legend-position)  [$page.position current]
1136    set _settings($this-legend-anchor)    [$page.anchor current]
1137   
1138    foreach option { -hide -position -anchor -borderwidth } {
1139        SetComponentOption legend $option
1140    }
1141    set _settings($this-legend-fontfamily)  [$page.fontfamily value]
1142    set _settings($this-legend-fontsize)    [$page.fontsize value]
1143    lappend font $_settings($this-legend-fontfamily)
1144    lappend font $_settings($this-legend-fontsize)
1145    lappend font $_settings($this-legend-fontweight)
1146    lappend font $_settings($this-legend-fontslant)
1147    $_clone legend configure -font fixed -font $font
1148    ApplyElementSettings
1149}
1150
1151itcl::body Rappture::XyPrint::ApplyAxisSettings {} {
1152    set axis [$itk_component(axis_combo) current]
1153    set type [GetAxisType $axis]
1154    set page $itk_component(axis_page)
1155    if { $_settings($this-axis-grid) } {
1156        $_clone grid configure -hide no -map${type} ${axis}
1157    } else {
1158        $_clone grid configure -hide no -map${type} ""
1159    }
1160    $_clone configure -plotpad${type} $_settings($this-axis-plotpad)
1161    foreach option { -min -max -loose -title -stepsize -subdivisions } {
1162        SetNamedComponentOption axis $axis $option
1163    }
1164    set _settings($this-axis-ticks-fontfamily)  [$page.tickfontfamily value]
1165    set _settings($this-axis-ticks-fontsize)    [$page.tickfontsize value]
1166    set _settings($this-axis-title-fontfamily)  [$page.titlefontfamily value]
1167    set _settings($this-axis-title-fontsize)    [$page.titlefontsize value]
1168
1169    set tickfont {}
1170    set titlefont {}
1171
1172    foreach attr { fontfamily fontsize fontweight fontslant } {
1173        set specific $this-$axis-ticks
1174        set general  $this-axis-ticks
1175        set _settings(${specific}-${attr}) $_settings(${general}-${attr})
1176        lappend tickfont $_settings(${general}-${attr})
1177        set specific $this-$axis-title
1178        set general  $this-axis-title
1179        set _settings(${specific}-${attr}) $_settings(${general}-${attr})
1180        lappend titlefont $_settings(${general}-${attr})
1181    }
1182    $_clone axis configure $axis -tickfont $tickfont -titlefont $titlefont
1183    $_clone marker configure ${type}-zero -hide $_settings($this-axis-zero)
1184    GetAxis
1185    RegeneratePreview
1186}
1187
1188itcl::body Rappture::XyPrint::ApplyElementSettings {} {
1189    set index [$itk_component(element_slider) get]
1190    set page $itk_component(legend_page)
1191    set _settings($this-element-color)  [$page.color current]
1192    if { $_clone != "" } {
1193        set elem $_settings($this-element-$index)
1194        if { [$_clone element type $elem] != "bar" } {
1195            set _settings($this-element-symbol) [$page.symbol current]
1196            set _settings($this-element-dashes) [$page.dashes current]
1197            foreach option { -symbol -dashes } {
1198                SetNamedComponentOption element $elem $option
1199            }
1200        }
1201        foreach option { -color -label } {
1202            SetNamedComponentOption element $elem $option
1203        }
1204        RegeneratePreview
1205    }
1206}
1207
1208itcl::body Rappture::XyPrint::SetLayoutOption { opt } {
1209    set new [Inches2Pixels $_settings($this-layout$opt)]
1210    $_clone configure $opt $new
1211}
1212
1213itcl::body Rappture::XyPrint::ApplyLayoutSettings {} {
1214    foreach opt { -width -height -leftmargin -rightmargin -topmargin
1215        -bottommargin } {
1216        set old [$_clone cget $opt]
1217        set code [catch { SetLayoutOption $opt } err]
1218        if { $code != 0 } {
1219            bell
1220            global errorInfo
1221            puts stderr "$err: $errorInfo"
1222            set _settings($this-layout$opt) [Pixels2Inches $old]
1223            $_clone configure $opt [Pixels2Inches $old]
1224        }
1225    }
1226    RegeneratePreview
1227}
1228
1229
1230itcl::body Rappture::XyPrint::InitializeSettings {} {
1231    # General settings
1232
1233    # Always set to "ps" "ieee"
1234    set _settings($this-general-format) ps
1235    set _settings($this-general-style) ieee
1236    set _settings($this-general-remember) 0
1237    set page $itk_component(graph_page)
1238    $page.format value [$page.format label $_settings($this-general-format)]
1239    $page.style value [$page.style label $_settings($this-general-style)]
1240
1241    # Layout settings
1242    set _settings($this-layout-width) [Pixels2Inches [$_clone cget -width]]
1243    set _settings($this-layout-height) [Pixels2Inches [$_clone cget -height]]
1244    set _settings($this-layout-leftmargin) \
1245        [Pixels2Inches [$_clone cget -leftmargin]]
1246    set _settings($this-layout-rightmargin) \
1247        [Pixels2Inches [$_clone cget -rightmargin]]
1248    set _settings($this-layout-topmargin) \
1249        [Pixels2Inches [$_clone cget -topmargin]]
1250    set _settings($this-layout-bottommargin) \
1251        [Pixels2Inches [$_clone cget -bottommargin]]
1252
1253    # Legend settings
1254    set page $itk_component(legend_page)
1255
1256    set names [$_clone element show]
1257    $itk_component(element_slider) configure -from 1 -to [llength $names]
1258    set state [expr  { ([llength $names] < 2) ? "disabled" : "normal" } ]
1259    $page.slider configure -state $state
1260    $page.slider_l configure -state $state
1261    # Always initialize the slider to the first entry in the element list.
1262    $itk_component(element_slider) set 1
1263    # Always set the borderwidth to be not displayed
1264    set _settings($this-legend-borderwidth) 0
1265
1266    $page.fontfamily value $_settings($this-legend-fontfamily)
1267    $page.fontsize value $_settings($this-legend-fontsize)
1268    if { $_settings($this-legend-fontweight) == "bold" } {
1269        set _settings($this-legend-font-bold) 1
1270    }
1271    set _settings($this-legend-hide) [$_clone legend cget -hide]
1272    set _settings($this-legend-position) [$_clone legend cget -position]
1273    set _settings($this-legend-anchor) [$_clone legend cget -anchor]
1274    $page.position value \
1275        [$page.position label $_settings($this-legend-position)]
1276    $page.anchor value [$page.anchor label $_settings($this-legend-anchor)]
1277    GetElement
1278
1279    # Axis settings
1280    set page $itk_component(axis_page)
1281    set names [lsort [$_clone axis names]]
1282    $itk_component(axis_combo) choices delete 0 end
1283    foreach axis $names {
1284        if { $axis == "z" } {
1285            continue
1286        }
1287        if { ![$_clone axis cget $axis -hide] } {
1288            $itk_component(axis_combo) choices insert end $axis $axis
1289        }
1290        lappend axisnames $axis
1291    }
1292    set axis [lindex $names 0]
1293
1294    $page.titlefontfamily value $_settings($this-$axis-title-fontfamily)
1295    $page.titlefontsize value   $_settings($this-$axis-title-fontsize)
1296    $page.tickfontfamily value  $_settings($this-$axis-ticks-fontfamily)
1297    $page.tickfontsize value    $_settings($this-$axis-ticks-fontsize)
1298
1299    # Always hide the zero line.
1300    set _settings($this-axis-zero) 1
1301    set _settings($this-axis-plotpad) [Pixels2Inches [$_clone cget -plotpadx]]
1302    # Pick the first axis to initially display
1303    set axis [lindex $axisnames 0]
1304    $itk_component(axis_combo) value $axis
1305    GetAxis
1306    RegeneratePreview
1307}
1308
1309
1310itcl::body Rappture::XyPrint::restore { toolName plotName data } {
1311    set key [list $toolName $plotName]
1312    set _savedSettings($key) $data
1313}
1314
1315itcl::body Rappture::XyPrint::RestoreSettings { toolName plotName } {
1316    if { ![file readable $_settingsFile] } {
1317        return;                         # No file or not readable
1318    }
1319    if { [file exists $_oldSettingsFile] } {
1320        file delete $_oldSettingsFile
1321    }
1322    # Read the file by sourcing it into a safe interpreter The only commands
1323    # executed will be "xyprint" which will simply add the data into an array
1324    # _savedSettings.
1325    set parser [interp create -safe]
1326    $parser alias xyprint [itcl::code $this restore]
1327    set f [open $_settingsFile "r"]
1328    set code [read $f]
1329    close $f
1330    if { [catch { $parser eval $code }] != 0 } {
1331        file delete $_settingsFiles
1332    }
1333    # Now see if there's an entry for this tool/plot combination.  The data
1334    # associated with the variable is itself code to update the graph (clone).
1335    set key [list $toolName $plotName]
1336    if { [info exists _savedSettings($key)] }  {
1337        $parser alias "preview" $_clone
1338        $parser eval $_savedSettings($key)
1339    }
1340    # Restore settings to this instance
1341    foreach {name value} [$parser eval "array get settings"] {
1342        set _settings($this-$name) $value
1343    }
1344    interp delete $parser
1345}
1346
1347itcl::body Rappture::XyPrint::ResetSettings {} {
1348    set graph $_graph
1349    DestroySettings
1350    set _graph $graph
1351    CloneGraph $graph
1352    InitClone
1353    InitializeSettings
1354}
1355
1356itcl::body Rappture::XyPrint::SaveSettings { toolName plotName } {
1357    if { !$_settings($this-general-remember) } {
1358        return
1359    }
1360    if { [catch { open $_settingsFile "w" 0600 } f ] != 0 } {
1361        puts stderr "$_settingsFile isn't writable: $f"
1362        bell
1363        return
1364    }
1365    set key [list $toolName $plotName]
1366    set _savedSettings($key) [CreateSettings $toolName $plotName]
1367    # Write the settings out
1368    foreach key [lsort [array names _savedSettings]] {
1369        set tool [lindex $key 0]
1370        set plot [lindex $key 1]
1371        puts $f "xyprint \"$tool\" \"$plot\" \{"
1372        set settings [string trim $_savedSettings($key) \n]
1373        puts $f "$settings"
1374        puts $f "\}\n"
1375    }
1376    close $f
1377}
1378
1379itcl::body Rappture::XyPrint::CreateSettings { toolName plotName } {
1380    # Create stanza associated with tool and plot title.
1381    # General settings
1382    set length [string length "${this}-"]
1383    append out "    array set settings {\n"
1384    foreach item [array names _settings ${this}-*] {
1385        set field [string range $item $length end]
1386        if { [regexp {^element-[0-9]+$} $field] } {
1387            continue
1388        }
1389        set value $_settings($item)
1390        append out "        [list $field] [list $value]\n"
1391    }
1392    append out "    }\n"
1393    # Legend font
1394    lappend legendfont $_settings($this-legend-fontfamily)
1395    lappend legendfont $_settings($this-legend-fontsize)
1396    lappend legendfont $_settings($this-legend-fontweight)
1397    lappend legendfont $_settings($this-legend-fontslant)
1398    # Axis tick font
1399    lappend axistickfont $_settings($this-axis-ticks-fontfamily)
1400    lappend axistickfont $_settings($this-axis-ticks-fontsize)
1401    lappend axistickfont $_settings($this-axis-ticks-fontweight)
1402    lappend axistickfont $_settings($this-axis-ticks-fontslant)
1403    # Axis title font
1404    lappend axistitlefont $_settings($this-axis-title-fontfamily)
1405    lappend axistitlefont $_settings($this-axis-title-fontsize)
1406    lappend axistitlefont $_settings($this-axis-title-fontweight)
1407    lappend axistitlefont $_settings($this-axis-title-fontslant)
1408    append out "\n"
1409
1410    # Layout settings
1411    append out "    preview configure"
1412    foreach opt { -width -height -leftmargin -rightmargin -topmargin
1413        -bottommargin -plotpadx -plotpady } {
1414        set value [$_clone cget $opt]
1415        append out " $opt [list $value]"
1416    }
1417    append out "\n"
1418
1419    # Legend settings
1420    append out "    preview legend configure"
1421    foreach opt { -position -anchor -borderwidth -hide } {
1422        set value [$_clone legend cget $opt]
1423        append out " $opt [list $value]"
1424    }
1425    append out " -font [list $legendfont]\n"
1426
1427    # Element settings
1428    foreach elem [$_clone element show] {
1429        set label [$_clone element cget $elem -label]
1430        if { $label == "" } {
1431            continue
1432        }
1433        set label [list $label]
1434        append out "    if \{ \[preview element exists $label] \} \{\n"
1435        append out "        preview element configure $label"
1436        if { [$_clone element type $elem] != "bar" } {
1437            set options { -symbol -color -dashes -label }
1438        } else {
1439            set options { -color -label }
1440        }
1441        foreach opt $options {
1442            set value [$_clone element cget $elem $opt]
1443            append out " $opt [list $value]"
1444        }
1445        append out "    \}\n"
1446    }
1447   
1448    # Axis settings
1449    foreach axis [$_clone axis names] {
1450        if { [$_clone axis cget $axis -hide] } {
1451            continue
1452        }
1453        set axis [list $axis]
1454        append out "    if \{ \[llength \[preview axis names $axis\]\] == 1 \} \{\n"
1455        append out "        preview axis configure $axis"
1456        foreach opt { -hide -min -max -loose -title -stepsize -subdivisions } {
1457            set value [$_clone axis cget $axis $opt]
1458            append out " $opt [list $value]"
1459        }
1460        append out " -tickfont [list $axistickfont]"
1461        append out " -titlefont [list $axistitlefont]\n"
1462        set hide [$_clone marker cget ${axis}-zero -hide]
1463        append out "        preview marker configure ${axis}-zero -hide $hide\n"
1464        append out "    \}\n"
1465    }   
1466
1467    append out "    preview grid configure"
1468    append out " -hide \"[$_clone grid cget -hide]\""
1469    append out " -mapx \"[$_clone grid cget -mapx]\""
1470    append out " -mapy \"[$_clone grid cget -mapy]\""
1471    return $out
1472}
Note: See TracBrowser for help on using the repository browser.