| # Download class implementation for Insight. |
| # Copyright (C) 1999, 2001 Red Hat, Inc. |
| # |
| # This program is free software; you can redistribute it and/or modify it |
| # under the terms of the GNU General Public License (GPL) as published by |
| # the Free Software Foundation; either version 2 of the License, or (at |
| # your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| |
| |
| # ---------------------------------------------------------------------- |
| # Download window and associated procs |
| # |
| # ---------------------------------------------------------------------- |
| |
| itcl::body Download::constructor {args} { |
| global gdb_pretty_name |
| debug $args |
| eval itk_initialize $args |
| window_name "Download Status" "Download" |
| add_hook download_progress_hook "$this update_download" |
| |
| label $itk_interior.dload -text "Downloading $filename to $gdb_pretty_name" |
| |
| label $itk_interior.stat |
| set f [frame $itk_interior.f] |
| |
| set i 0 |
| while {$i <$num_sections} { |
| iwidgets::feedback $f.meter$i -steps $num_steps |
| grid forget [$f.meter$i component percentage] |
| label $f.sec$i -text [lindex $section(names) $i] -anchor w |
| label $f.num$i -text $bytes($i) -anchor e |
| grid $f.sec$i $f.meter$i $f.num$i -padx 4 -pady 4 -sticky news |
| incr i |
| } |
| grid columnconfigure $f 1 -weight 1 |
| |
| button $itk_interior.cancel -text Cancel -command "$this cancel" \ |
| -state active -width 10 |
| |
| pack $itk_interior.dload -padx 5 -pady 5 -side top -fill x -expand yes |
| pack $itk_interior.stat -padx 5 -pady 5 -expand yes |
| pack $itk_interior.f -padx 5 -pady 5 -fill x -expand yes |
| |
| pack $itk_interior.cancel -padx 5 -pady 5 -side bottom |
| ::update idletasks |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: update_download - update the download meters |
| # ------------------------------------------------------------------ |
| itcl::body Download::update_download { sec num tot } { |
| |
| # Loop through all the sections, marking each as either done or |
| # updating its meter. This will mark all previous sections prior to |
| # SEC as complete. |
| foreach s $section(names) { |
| set i $section($s) |
| |
| if {$s == $sec} { |
| # Advance feedback meter. The iwidgets meter leaves a lot to |
| # be desired. No way to query the current setting. No way to |
| # set the state of the meter by percentage. It only understands |
| # steps, and we must be careful not to step the widget past the |
| # the configured number of steps, or else the meter will be |
| # set wrong. How lame. |
| set steps [expr {$num / $bytes($i) * $num_steps}] |
| if {[expr {$completed_steps($s) + $steps}] > $num_steps} { |
| set steps [expr {$num_steps - $completed_steps($s)}] |
| } |
| incr completed_steps($s) $steps |
| $itk_interior.f.meter$i step $steps |
| break |
| } else { |
| # Section already loaded. Make sure meter is at 100%. |
| if {$completed_steps($s) < $num_steps} { |
| set steps [expr {$num_steps - $completed_steps($s)}] |
| set completed_steps($s) $num_steps |
| $itk_interior.f.meter$i step $steps |
| } |
| } |
| } |
| |
| ::update |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: done - notification that the download is really complete |
| # ------------------------------------------------------------------ |
| itcl::body Download::done { {msg ""} } { |
| bell |
| |
| if {$msg == ""} { |
| # download finished |
| set secs [expr {[clock seconds] - $::download_start_time}] |
| if {$secs == 0} { incr secs } |
| $itk_interior.cancel config -state disabled |
| set bps [expr {8 * $total_bytes / $secs / 1000}] |
| $itk_interior.stat config -text "$total_bytes bytes in $secs seconds ($bps kbps)" |
| |
| # set all indicators to FULL |
| foreach sec $section(names) { |
| set i $section($sec) |
| if {$completed_steps($sec) < $num_steps} { |
| set steps [expr {$num_steps - $completed_steps($sec)}] |
| set completed_steps($sec) $num_steps |
| $itk_interior.f.meter$i step $steps |
| } |
| } |
| } else { |
| # download failed |
| if {$msg != "CANCEL"} { |
| $itk_interior.stat config -text $msg |
| } |
| } |
| |
| # enable OK button |
| $itk_interior.cancel config -state active -text OK -command "delete object $this" |
| ::update |
| } |
| |
| # ------------------------------------------------------------------ |
| # METHOD: cancel - cancel the download |
| # ------------------------------------------------------------------ |
| itcl::body Download::cancel {} { |
| debug "canceling the download" |
| set ::download_cancel_ok 1 |
| } |
| |
| # ------------------------------------------------------------------ |
| # DESTRUCTOR - destroy window containing widget |
| # ------------------------------------------------------------------ |
| itcl::body Download::destructor {} { |
| remove_hook download_progress_hook "$this update_download" |
| } |
| |
| itcl::body Download::do_download_hooks {} { |
| set ::download_timer(ok) 1 |
| } |
| |
| itcl::body Download::download_hash { section num } { |
| global download_timer |
| debug "sec=$section num=$num tot=$total_bytes ok=$::download_cancel_ok" |
| ::update |
| # Only run the timer at discrete times... |
| if {[info exists download_timer(timer)]} { |
| after cancel $download_timer(timer) |
| } |
| |
| set download_timer(timer) [after 100 Download::do_download_hooks] |
| if {![info exists download_timer(ok)] || $download_timer(ok)} { |
| run_hooks download_progress_hook $section $num $total_bytes |
| ::update |
| unset download_timer(timer) |
| set download_timer(ok) 0 |
| } |
| |
| return $::download_cancel_ok |
| } |
| |
| # Download the executable. Return zero for success, and non-zero for error. |
| itcl::body Download::download_it { } { |
| global gdb_exe_name gdb_downloading gdb_loaded |
| global gdb_target_name gdb_pretty_name |
| global gdb_running gdbtk_platform |
| |
| debug "exe=$gdb_exe_name downloading=$gdb_downloading" |
| debug " loaded=$gdb_loaded target=$gdb_target_name running=$gdb_running" |
| |
| if {$gdb_downloading || $gdb_exe_name == ""} { |
| return 0 |
| } |
| |
| set gdb_downloading 1 |
| set gdb_loaded 0 |
| # Make sure the source window has had time to be created |
| ::update |
| |
| gdbtk_busy |
| |
| # Only places that load files should do set_exe |
| #set_exe |
| switch [set_target] { |
| ERROR { |
| # target command failed |
| set gdb_downloading 0 |
| gdbtk_idle |
| return 0 |
| } |
| CANCELED { |
| # command cancelled by user |
| set gdb_downloading 0 |
| if {$gdb_running} { |
| # Run the idle hooks (free the UI) |
| gdbtk_update |
| gdbtk_idle |
| } else { |
| gdbtk_idle |
| } |
| return 1 |
| } |
| } |
| |
| if {[string compare $gdbtk_platform(os) "cygwin"] == 0} { |
| set f [ide_cygwin_path to_win32 $gdb_exe_name] |
| } else { |
| set f $gdb_exe_name |
| } |
| if {! [file exists $f]} { |
| tk_messageBox -icon error -title GDB -type ok \ |
| -message "Request to download non-existent executable $gdb_exe_name" |
| set gdb_downloading 0 |
| gdbtk_idle |
| return 0 |
| } |
| |
| debug "downloading $gdb_exe_name" |
| |
| set target $gdb_target_name |
| |
| # get load info and total up number of bytes |
| if {[catch {gdb_load_info $gdb_exe_name} val]} { |
| set result "$gdb_exe_name: $val" |
| tk_dialog .load_warn "" "$result" error 0 Ok |
| return 0 |
| } |
| set i 0 |
| set total_bytes 0 |
| set section(names) {} |
| foreach x $val { |
| set s [lindex $x 0] |
| lappend section(names) $s |
| set section($s) $i |
| set b [lindex $x 1] |
| set bytes($i) [expr {double($b)}] |
| incr total_bytes $b |
| set completed_steps($s) 0 |
| incr i |
| } |
| set num_sections $i |
| |
| set ::download_cancel_ok 0 |
| set ::download_start_time [clock seconds] |
| |
| if {[pref getd gdb/load/$target-verbose] == "1"} { |
| # open a detailed download dialog window |
| set download_dialog [ManagedWin::open Download -transient -filename $gdb_exe_name] |
| } else { |
| # raise source windows |
| foreach src [ManagedWin::find SrcWin] { |
| $src reveal |
| $src toolbar downloading |
| } |
| set download_dialog "" |
| } |
| |
| set download_error "" |
| debug "starting load" |
| ::update idletasks |
| if {[catch {gdb_cmd "load $gdb_exe_name"} errTxt]} { |
| debug "load returned $errTxt" |
| if {[regexp -nocase cancel $errTxt]} { |
| set download_error "CANCEL" |
| } else { |
| set download_error $errTxt |
| } |
| set ::download_cancel_ok 1 |
| } |
| |
| debug "Done loading" |
| |
| set gdb_downloading 0 |
| if {$::download_cancel_ok} { |
| set gdb_loaded 0 |
| if {$download_dialog != ""} { |
| catch {$download_dialog done $download_error} |
| } |
| } else { |
| set gdb_loaded 1 |
| if {$download_dialog != ""} { |
| catch {$download_dialog done} |
| } |
| } |
| |
| foreach src [ManagedWin::find SrcWin] { |
| if {$download_error == "CANCEL"} { |
| $src download_progress CANCEL 1 1 |
| } else { |
| $src download_progress DONE 0 $total_bytes $download_error |
| } |
| } |
| |
| set ::download_cancel_ok 0 |
| set download_dialog "" |
| |
| gdbtk_idle |
| return 0 |
| } |