You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
304 lines
8.7 KiB
Plaintext
304 lines
8.7 KiB
Plaintext
15 years ago
|
# 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
|
||
|
}
|