home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / bgerror.tcl < prev    next >
Text File  |  2003-09-01  |  9KB  |  293 lines

  1. # bgerror.tcl --
  2. #
  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.
  8. #
  9. # Copyright (c) 1998-2000 by Ajuba Solutions.
  10. # All rights reserved.
  11. # RCS: @(#) $Id: bgerror.tcl,v 1.23 2002/08/31 06:12:28 das Exp $
  12. # $Id: bgerror.tcl,v 1.23 2002/08/31 06:12:28 das Exp $
  13.  
  14. namespace eval ::tk {
  15.     namespace eval dialog {
  16.     namespace eval error {
  17.         namespace import ::tk::msgcat::*
  18.         namespace export bgerror
  19.         option add *ErrorDialog.function.text [mc "Save To Log"] \
  20.             widgetDefault
  21.         option add *ErrorDialog.function.command [namespace code SaveToLog]
  22.     }
  23.     }
  24. }
  25.  
  26. proc ::tk::dialog::error::Return {} {
  27.     variable button
  28.     
  29.     .bgerrorDialog.ok configure -state active -relief sunken
  30.     update idletasks
  31.     after 100
  32.     set button 0
  33. }
  34.  
  35. proc ::tk::dialog::error::Details {} {
  36.     set w .bgerrorDialog
  37.     set caption [option get $w.function text {}]
  38.     set command [option get $w.function command {}]
  39.     if { ($caption eq "") || ($command eq "") } {
  40.     grid forget $w.function
  41.     }
  42.     $w.function configure -text $caption -command \
  43.     "$command [list [.bgerrorDialog.top.info.text get 1.0 end]]"
  44.     grid $w.top.info - -sticky nsew -padx 3m -pady 3m
  45. }
  46.  
  47. proc ::tk::dialog::error::SaveToLog {text} {
  48.     if { $::tcl_platform(platform) eq "windows" } {
  49.     set allFiles *.*
  50.     } else {
  51.     set allFiles *
  52.     }
  53.     set types [list    \
  54.         [list [mc "Log Files"] .log]    \
  55.         [list [mc "Text Files"] .txt]    \
  56.         [list [mc "All Files"] $allFiles] \
  57.         ]
  58.     set filename [tk_getSaveFile -title [mc "Select Log File"] \
  59.         -filetypes $types -defaultextension .log -parent .bgerrorDialog]
  60.     if {![string length $filename]} {
  61.     return
  62.     }
  63.     set f [open $filename w]
  64.     puts -nonewline $f $text
  65.     close $f
  66. }
  67.  
  68. proc ::tk::dialog::error::Destroy {w} {
  69.     if {$w eq ".bgerrorDialog"} {
  70.     variable button
  71.     set button -1
  72.     }
  73. }
  74.  
  75. # ::tk::dialog::error::bgerror --
  76. # This is the default version of bgerror. 
  77. # It tries to execute tkerror, if that fails it posts a dialog box containing
  78. # the error message and gives the user a chance to ask to see a stack
  79. # trace.
  80. # Arguments:
  81. # err -            The error message.
  82.  
  83. proc ::tk::dialog::error::bgerror err {
  84.     global errorInfo tcl_platform
  85.     variable button
  86.  
  87.     set info $errorInfo
  88.  
  89.     set ret [catch {::tkerror $err} msg];
  90.     if {$ret != 1} {return -code $ret $msg}
  91.  
  92.     # Ok the application's tkerror either failed or was not found
  93.     # we use the default dialog then :
  94.     if {($tcl_platform(platform) eq "macintosh")
  95.              || ([tk windowingsystem] eq "aqua")} {
  96.     set ok        [mc Ok]
  97.     set messageFont    system
  98.     set textRelief    flat
  99.     set textHilight    0
  100.     } else {
  101.     set ok        [mc OK]
  102.     set messageFont    {Times -18}
  103.     set textRelief    sunken
  104.     set textHilight    1
  105.     }
  106.  
  107.  
  108.     # Truncate the message if it is too wide (longer than 30 characacters) or
  109.     # too tall (more than 4 newlines).  Truncation occurs at the first point at
  110.     # which one of those conditions is met.
  111.     set displayedErr ""
  112.     set lines 0
  113.     foreach line [split $err \n] {
  114.     if { [string length $line] > 30 } {
  115.         append displayedErr "[string range $line 0 29]..."
  116.         break
  117.     }
  118.     if { $lines > 4 } {
  119.         append displayedErr "..."
  120.         break
  121.     } else {
  122.         append displayedErr "${line}\n"
  123.     }
  124.     incr lines
  125.     }
  126.  
  127.     set w .bgerrorDialog
  128.     set title [mc "Application Error"]
  129.     set text [mc {Error: %1$s} $err]
  130.     set buttons [list ok $ok dismiss [mc "Skip Messages"] \
  131.         function [mc "Details >>"]]
  132.  
  133.     # 1. Create the top-level window and divide it into top
  134.     # and bottom parts.
  135.  
  136.     catch {destroy .bgerrorDialog}
  137.     toplevel .bgerrorDialog -class ErrorDialog
  138.     wm title .bgerrorDialog $title
  139.     wm iconname .bgerrorDialog ErrorDialog
  140.     wm protocol .bgerrorDialog WM_DELETE_WINDOW { }
  141.  
  142.     if {($tcl_platform(platform) eq "macintosh") 
  143.             || ([tk windowingsystem] eq "aqua")} {
  144.     ::tk::unsupported::MacWindowStyle style .bgerrorDialog dBoxProc
  145.     }
  146.  
  147.     frame .bgerrorDialog.bot
  148.     frame .bgerrorDialog.top
  149.     if {[tk windowingsystem] eq "x11"} {
  150.     .bgerrorDialog.bot configure -relief raised -bd 1
  151.     .bgerrorDialog.top configure -relief raised -bd 1
  152.     }
  153.     pack .bgerrorDialog.bot -side bottom -fill both
  154.     pack .bgerrorDialog.top -side top -fill both -expand 1
  155.  
  156.     set W [frame $w.top.info]
  157.     text $W.text                \
  158.         -bd 2                \
  159.         -yscrollcommand [list $W.scroll set]\
  160.         -setgrid true            \
  161.         -width 40                \
  162.         -height 10                \
  163.         -state normal            \
  164.         -relief $textRelief            \
  165.         -highlightthickness $textHilight    \
  166.         -wrap char
  167.  
  168.     scrollbar $W.scroll -relief sunken -command [list $W.text yview]
  169.     pack $W.scroll -side right -fill y
  170.     pack $W.text -side left -expand yes -fill both
  171.     $W.text insert 0.0 "$err\n$info"
  172.     $W.text mark set insert 0.0
  173.     bind $W.text <ButtonPress-1> { focus %W }
  174.     $W.text configure -state disabled
  175.  
  176.     # 2. Fill the top part with bitmap and message
  177.  
  178.     # Max-width of message is the width of the screen...
  179.     set wrapwidth [winfo screenwidth .bgerrorDialog]
  180.     # ...minus the width of the icon, padding and a fudge factor for
  181.     # the window manager decorations and aesthetics.
  182.     set wrapwidth [expr {$wrapwidth-60-[winfo pixels .bgerrorDialog 9m]}]
  183.     label .bgerrorDialog.msg -justify left -text $text -font $messageFont \
  184.         -wraplength $wrapwidth
  185.     if {($tcl_platform(platform) eq "macintosh")
  186.             || ([tk windowingsystem] eq "aqua")} {
  187.     # On the Macintosh, use the stop bitmap
  188.     label .bgerrorDialog.bitmap -bitmap stop
  189.     } else {
  190.     # On other platforms, make the error icon
  191.     canvas .bgerrorDialog.bitmap -width 32 -height 32 -highlightthickness 0
  192.     .bgerrorDialog.bitmap create oval 0 0 31 31 -fill red -outline black
  193.     .bgerrorDialog.bitmap create line 9 9 23 23 -fill white -width 4
  194.     .bgerrorDialog.bitmap create line 9 23 23 9 -fill white -width 4
  195.     }
  196.     grid .bgerrorDialog.bitmap .bgerrorDialog.msg \
  197.         -in .bgerrorDialog.top    \
  198.         -row 0            \
  199.         -padx 3m            \
  200.         -pady 3m
  201.     grid configure     .bgerrorDialog.msg -sticky nsw -padx {0 3m}
  202.     grid rowconfigure     .bgerrorDialog.top 1 -weight 1
  203.     grid columnconfigure .bgerrorDialog.top 1 -weight 1
  204.  
  205.     # 3. Create a row of buttons at the bottom of the dialog.
  206.  
  207.     set i 0
  208.     foreach {name caption} $buttons {
  209.     button .bgerrorDialog.$name    \
  210.         -text $caption        \
  211.         -default normal        \
  212.         -command [namespace code "set button $i"]
  213.     grid .bgerrorDialog.$name    \
  214.         -in .bgerrorDialog.bot    \
  215.         -column $i        \
  216.         -row 0            \
  217.         -sticky ew        \
  218.         -padx 10
  219.     grid columnconfigure .bgerrorDialog.bot $i -weight 1
  220.     # We boost the size of some Mac buttons for l&f
  221.     if {($tcl_platform(platform) eq "macintosh")
  222.         || ([tk windowingsystem] eq "aqua")} {
  223.         if {($name eq "ok") || ($name eq "dismiss")} {
  224.         grid columnconfigure .bgerrorDialog.bot $i -minsize 79
  225.         }
  226.     }
  227.     incr i
  228.     }
  229.     # The "OK" button is the default for this dialog.
  230.     .bgerrorDialog.ok configure -default active
  231.  
  232.     bind .bgerrorDialog <Return>    [namespace code Return]
  233.     bind .bgerrorDialog <Destroy>    [namespace code [list Destroy %W]]
  234.     .bgerrorDialog.function configure -command [namespace code Details]
  235.  
  236.     # 6. Withdraw the window, then update all the geometry information
  237.     # so we know how big it wants to be, then center the window in the
  238.     # display and de-iconify it.
  239.  
  240.     wm withdraw .bgerrorDialog
  241.     update idletasks
  242.     set parent [winfo parent    .bgerrorDialog]
  243.     set width  [winfo reqwidth    .bgerrorDialog]
  244.     set height [winfo reqheight    .bgerrorDialog]
  245.     set x [expr {([winfo screenwidth .bgerrorDialog]  - $width )/2 - \
  246.         [winfo vrootx $parent]}]
  247.     set y [expr {([winfo screenheight .bgerrorDialog] - $height)/2 - \
  248.         [winfo vrooty $parent]}]
  249.     .bgerrorDialog configure -width $width
  250.     wm geometry .bgerrorDialog +$x+$y
  251.     wm deiconify .bgerrorDialog
  252.  
  253.     # 7. Set a grab and claim the focus too.
  254.  
  255.     set oldFocus [focus]
  256.     set oldGrab [grab current .bgerrorDialog]
  257.     if {$oldGrab != ""} {
  258.     set grabStatus [grab status $oldGrab]
  259.     }
  260.     grab .bgerrorDialog
  261.     focus .bgerrorDialog.ok
  262.  
  263.     # 8. Wait for the user to respond, then restore the focus and
  264.     # return the index of the selected button.  Restore the focus
  265.     # before deleting the window, since otherwise the window manager
  266.     # may take the focus away so we can't redirect it.  Finally,
  267.     # restore any grab that was in effect.
  268.  
  269.     vwait [namespace which -variable button]
  270.     set copy $button; # Save a copy...
  271.     catch {focus $oldFocus}
  272.     catch {destroy .bgerrorDialog}
  273.     if {$oldGrab ne ""} {
  274.     if {$grabStatus eq "global"} {
  275.         grab -global $oldGrab
  276.     } else {
  277.         grab $oldGrab
  278.     }
  279.     }
  280.  
  281.     if {$copy == 1} {
  282.     return -code break
  283.     }
  284. }
  285.  
  286. namespace eval :: {
  287.     # Fool the indexer
  288.     proc bgerror err {}
  289.     rename bgerror {}
  290.     namespace import ::tk::dialog::error::bgerror
  291. }
  292.