Update tk to version 8.5.13
[msysgit.git] / mingw / lib / tk8.5 / bgerror.tcl
blobf46ab4c6459a43209ceacc312f0cb859eb9efea9
1 # bgerror.tcl --
3 # Implementation of the bgerror procedure. It posts a dialog box with
4 # the error message and gives the user a chance to see a more detailed
5 # stack trace, and possible do something more interesting with that
6 # trace (like save it to a log). This is adapted from work done by
7 # Donal K. Fellows.
9 # Copyright (c) 1998-2000 by Ajuba Solutions.
10 # Copyright (c) 2007 by ActiveState Software Inc.
11 # Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
13 namespace eval ::tk::dialog::error {
14 namespace import -force ::tk::msgcat::*
15 namespace export bgerror
16 option add *ErrorDialog.function.text [mc "Save To Log"] \
17 widgetDefault
18 option add *ErrorDialog.function.command [namespace code SaveToLog]
19 option add *ErrorDialog*Label.font TkCaptionFont widgetDefault
20 if {[tk windowingsystem] eq "aqua"} {
21 option add *ErrorDialog*background systemAlertBackgroundActive \
22 widgetDefault
23 option add *ErrorDialog*info.text.background white widgetDefault
24 option add *ErrorDialog*Button.highlightBackground \
25 systemAlertBackgroundActive widgetDefault
29 proc ::tk::dialog::error::Return {} {
30 variable button
32 .bgerrorDialog.ok configure -state active -relief sunken
33 update idletasks
34 after 100
35 set button 0
38 proc ::tk::dialog::error::Details {} {
39 set w .bgerrorDialog
40 set caption [option get $w.function text {}]
41 set command [option get $w.function command {}]
42 if { ($caption eq "") || ($command eq "") } {
43 grid forget $w.function
45 lappend command [$w.top.info.text get 1.0 end-1c]
46 $w.function configure -text $caption -command $command
47 grid $w.top.info - -sticky nsew -padx 3m -pady 3m
50 proc ::tk::dialog::error::SaveToLog {text} {
51 if { $::tcl_platform(platform) eq "windows" } {
52 set allFiles *.*
53 } else {
54 set allFiles *
56 set types [list \
57 [list [mc "Log Files"] .log] \
58 [list [mc "Text Files"] .txt] \
59 [list [mc "All Files"] $allFiles] \
61 set filename [tk_getSaveFile -title [mc "Select Log File"] \
62 -filetypes $types -defaultextension .log -parent .bgerrorDialog]
63 if {![string length $filename]} {
64 return
66 set f [open $filename w]
67 puts -nonewline $f $text
68 close $f
71 proc ::tk::dialog::error::Destroy {w} {
72 if {$w eq ".bgerrorDialog"} {
73 variable button
74 set button -1
78 # ::tk::dialog::error::bgerror --
79 # This is the default version of bgerror.
80 # It tries to execute tkerror, if that fails it posts a dialog box containing
81 # the error message and gives the user a chance to ask to see a stack
82 # trace.
83 # Arguments:
84 # err - The error message.
86 proc ::tk::dialog::error::bgerror err {
87 global errorInfo tcl_platform
88 variable button
90 set info $errorInfo
92 set ret [catch {::tkerror $err} msg];
93 if {$ret != 1} {return -code $ret $msg}
95 # Ok the application's tkerror either failed or was not found
96 # we use the default dialog then :
97 set windowingsystem [tk windowingsystem]
98 if {$windowingsystem eq "aqua"} {
99 set ok [mc Ok]
100 } else {
101 set ok [mc OK]
104 # Truncate the message if it is too wide (>maxLine characters) or
105 # too tall (>4 lines). Truncation occurs at the first point at
106 # which one of those conditions is met.
107 set displayedErr ""
108 set lines 0
109 set maxLine 45
110 foreach line [split $err \n] {
111 if { [string length $line] > $maxLine } {
112 append displayedErr "[string range $line 0 [expr {$maxLine-3}]]..."
113 break
115 if { $lines > 4 } {
116 append displayedErr "..."
117 break
118 } else {
119 append displayedErr "${line}\n"
121 incr lines
124 set title [mc "Application Error"]
125 set text [mc "Error: %1\$s" $displayedErr]
126 set buttons [list ok $ok dismiss [mc "Skip Messages"] \
127 function [mc "Details >>"]]
129 # 1. Create the top-level window and divide it into top
130 # and bottom parts.
132 set dlg .bgerrorDialog
133 destroy $dlg
134 toplevel $dlg -class ErrorDialog
135 wm withdraw $dlg
136 wm title $dlg $title
137 wm iconname $dlg ErrorDialog
138 wm protocol $dlg WM_DELETE_WINDOW { }
140 if {$windowingsystem eq "aqua"} {
141 ::tk::unsupported::MacWindowStyle style $dlg moveableAlert {}
142 } elseif {$windowingsystem eq "x11"} {
143 wm attributes $dlg -type dialog
146 frame $dlg.bot
147 frame $dlg.top
148 if {$windowingsystem eq "x11"} {
149 $dlg.bot configure -relief raised -bd 1
150 $dlg.top configure -relief raised -bd 1
152 pack $dlg.bot -side bottom -fill both
153 pack $dlg.top -side top -fill both -expand 1
155 set W [frame $dlg.top.info]
156 text $W.text -setgrid true -height 10 -wrap char \
157 -yscrollcommand [list $W.scroll set]
158 if {$windowingsystem ne "aqua"} {
159 $W.text configure -width 40
162 scrollbar $W.scroll -command [list $W.text yview]
163 pack $W.scroll -side right -fill y
164 pack $W.text -side left -expand yes -fill both
165 $W.text insert 0.0 "$err\n$info"
166 $W.text mark set insert 0.0
167 bind $W.text <ButtonPress-1> { focus %W }
168 $W.text configure -state disabled
170 # 2. Fill the top part with bitmap and message
172 # Max-width of message is the width of the screen...
173 set wrapwidth [winfo screenwidth $dlg]
174 # ...minus the width of the icon, padding and a fudge factor for
175 # the window manager decorations and aesthetics.
176 set wrapwidth [expr {$wrapwidth-60-[winfo pixels $dlg 9m]}]
177 label $dlg.msg -justify left -text $text -wraplength $wrapwidth
178 if {$windowingsystem eq "aqua"} {
179 # On the Macintosh, use the stop bitmap
180 label $dlg.bitmap -bitmap stop
181 } else {
182 # On other platforms, make the error icon
183 canvas $dlg.bitmap -width 32 -height 32 -highlightthickness 0
184 $dlg.bitmap create oval 0 0 31 31 -fill red -outline black
185 $dlg.bitmap create line 9 9 23 23 -fill white -width 4
186 $dlg.bitmap create line 9 23 23 9 -fill white -width 4
188 grid $dlg.bitmap $dlg.msg -in $dlg.top -row 0 -padx 3m -pady 3m
189 grid configure $dlg.msg -sticky nsw -padx {0 3m}
190 grid rowconfigure $dlg.top 1 -weight 1
191 grid columnconfigure $dlg.top 1 -weight 1
193 # 3. Create a row of buttons at the bottom of the dialog.
195 set i 0
196 foreach {name caption} $buttons {
197 button $dlg.$name -text $caption -default normal \
198 -command [namespace code [list set button $i]]
199 grid $dlg.$name -in $dlg.bot -column $i -row 0 -sticky ew -padx 10
200 grid columnconfigure $dlg.bot $i -weight 1
201 # We boost the size of some Mac buttons for l&f
202 if {$windowingsystem eq "aqua"} {
203 if {($name eq "ok") || ($name eq "dismiss")} {
204 grid columnconfigure $dlg.bot $i -minsize 90
206 grid configure $dlg.$name -pady 7
208 incr i
210 # The "OK" button is the default for this dialog.
211 $dlg.ok configure -default active
213 bind $dlg <Return> [namespace code Return]
214 bind $dlg <Destroy> [namespace code [list Destroy %W]]
215 $dlg.function configure -command [namespace code Details]
217 # 6. Withdraw the window, then update all the geometry information
218 # so we know how big it wants to be, then center the window in the
219 # display (Motif style) and de-iconify it.
221 ::tk::PlaceWindow $dlg
223 # 7. Ensure that we are topmost.
225 raise $dlg
226 if {[tk windowingsystem] eq "win32"} {
227 # Place it topmost if we aren't at the top of the stacking
228 # order to ensure that it's seen
229 if {[lindex [wm stackorder .] end] ne "$dlg"} {
230 wm attributes $dlg -topmost 1
234 # 8. Set a grab and claim the focus too.
236 ::tk::SetFocusGrab $dlg $dlg.ok
238 # 9. Wait for the user to respond, then restore the focus and
239 # return the index of the selected button. Restore the focus
240 # before deleting the window, since otherwise the window manager
241 # may take the focus away so we can't redirect it. Finally,
242 # restore any grab that was in effect.
244 vwait [namespace which -variable button]
245 set copy $button; # Save a copy...
247 ::tk::RestoreFocusGrab $dlg $dlg.ok destroy
249 if {$copy == 1} {
250 return -code break
254 namespace eval :: {
255 # Fool the indexer
256 proc bgerror err {}
257 rename bgerror {}
258 namespace import ::tk::dialog::error::bgerror