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