3 # Implements messageboxes for platforms that do not have native
6 # SCCS: @(#) msgbox.tcl 1.8 97/07/28 17:20:01
8 # Copyright (c) 1994-1997 Sun Microsystems, Inc.
10 # See the file "license.terms" for information on usage and redistribution
11 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
17 # Pops up a messagebox with an application-supplied message with
18 # an icon and a list of buttons. This procedure will be called
19 # by tk_messageBox if the platform does not have native
20 # messagebox support, or if the particular type of messagebox is
21 # not supported natively.
23 # This procedure is a private procedure shouldn't be called
24 # directly. Call tk_messageBox instead.
26 # See the user documentation for details on what tk_messageBox does.
28 proc tkMessageBox {args} {
29 global tkPriv tcl_platform
35 # The default value of the title is space (" ") not the empty string
36 # because for some window managers, a
38 # causes the window title to be "foo" instead of the empty string.
49 tclParseConfigSpec $w $specs "" $args
51 if {[lsearch {info warning error question} $data(-icon)] == -1} {
52 error "invalid icon \"$data(-icon)\", must be error, info, question or warning"
54 if {$tcl_platform(platform) == "macintosh"} {
55 if {$data(-icon) == "error"} {
56 set data(-icon) "stop"
57 } elseif {$data(-icon) == "warning"} {
58 set data(-icon) "caution"
59 } elseif {$data(-icon) == "info"} {
60 set data(-icon) "note"
64 if ![winfo exists $data(-parent)] {
65 error "bad window path name \"$data(-parent)\""
71 {abort -width 6 -text Abort -under 0}
72 {retry -width 6 -text Retry -under 0}
73 {ignore -width 6 -text Ignore -under 0}
78 {ok -width 6 -text OK -under 0}
80 if {$data(-default) == ""} {
81 set data(-default) "ok"
86 {ok -width 6 -text OK -under 0}
87 {cancel -width 6 -text Cancel -under 0}
92 {retry -width 6 -text Retry -under 0}
93 {cancel -width 6 -text Cancel -under 0}
98 {yes -width 6 -text Yes -under 0}
99 {no -width 6 -text No -under 0}
104 {yes -width 6 -text Yes -under 0}
105 {no -width 6 -text No -under 0}
106 {cancel -width 6 -text Cancel -under 0}
110 error "invalid message box type \"$data(-type)\", must be abortretryignore, ok, okcancel, retrycancel, yesno or yesnocancel"
114 if [string compare $data(-default) ""] {
116 foreach btn $buttons {
117 if ![string compare [lindex $btn 0] $data(-default)] {
123 error "invalid default button \"$data(-default)\""
127 # 2. Set the dialog to be a child window of $parent
130 if [string compare $data(-parent) .] {
131 set w $data(-parent).__tk__messagebox
133 set w .__tk__messagebox
136 # 3. Create the top-level window and divide it into top
140 toplevel $w -class Dialog
141 wm title $w $data(-title)
142 wm iconname $w Dialog
143 wm protocol $w WM_DELETE_WINDOW { }
144 wm transient $w $data(-parent)
145 if {$tcl_platform(platform) == "macintosh"} {
146 unsupported1 style $w dBoxProc
150 pack $w.bot -side bottom -fill both
152 pack $w.top -side top -fill both -expand 1
153 if {$tcl_platform(platform) != "macintosh"} {
154 $w.bot configure -relief raised -bd 1
155 $w.top configure -relief raised -bd 1
158 # 4. Fill the top part with bitmap and message (use the option
159 # database for -wraplength so that it can be overridden by
162 option add *Dialog.msg.wrapLength 3i widgetDefault
163 label $w.msg -justify left -text $data(-message)
164 catch {$w.msg configure -font \
165 -Adobe-Times-Medium-R-Normal--*-180-*-*-*-*-*-*
167 pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m
168 if {$data(-icon) != ""} {
169 label $w.bitmap -bitmap $data(-icon)
170 pack $w.bitmap -in $w.top -side left -padx 3m -pady 3m
173 # 5. Create a row of buttons at the bottom of the dialog.
176 foreach but $buttons {
177 set name [lindex $but 0]
178 set opts [lrange $but 1 end]
179 if ![string compare $opts {}] {
180 # Capitalize the first letter of $name
183 [string index $name 0]][string range $name 1 end]
184 set opts [list -text $capName]
187 eval button $w.$name $opts -command [list "set tkPriv(button) $name"]
189 if ![string compare $name $data(-default)] {
190 $w.$name configure -default active
192 pack $w.$name -in $w.bot -side left -expand 1 \
195 # create the binding for the key accelerator, based on the underline
197 set underIdx [$w.$name cget -under]
198 if {$underIdx >= 0} {
199 set key [string index [$w.$name cget -text] $underIdx]
200 bind $w <Alt-[string tolower $key]> "$w.$name invoke"
201 bind $w <Alt-[string toupper $key]> "$w.$name invoke"
206 # 6. Create a binding for <Return> on the dialog if there is a
209 if [string compare $data(-default) ""] {
210 bind $w <Return> "tkButtonInvoke $w.$data(-default)"
213 # 7. Withdraw the window, then update all the geometry information
214 # so we know how big it wants to be, then center the window in the
215 # display and de-iconify it.
219 set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \
220 - [winfo vrootx [winfo parent $w]]]
221 set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2 \
222 - [winfo vrooty [winfo parent $w]]]
226 # 8. Set a grab and claim the focus too.
229 set oldGrab [grab current $w]
230 if {$oldGrab != ""} {
231 set grabStatus [grab status $oldGrab]
234 if [string compare $data(-default) ""] {
235 focus $w.$data(-default)
240 # 9. Wait for the user to respond, then restore the focus and
241 # return the index of the selected button. Restore the focus
242 # before deleting the window, since otherwise the window manager
243 # may take the focus away so we can't redirect it. Finally,
244 # restore any grab that was in effect.
246 tkwait variable tkPriv(button)
247 catch {focus $oldFocus}
249 if {$oldGrab != ""} {
250 if {$grabStatus == "global"} {
251 grab -global $oldGrab
256 return $tkPriv(button)