# Local Variable Window for Insight. # Copyright 2002, 2003 Red Hat # # 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. # ---------------------------------------------------------------------- # Implements local variables windows for gdb. # ---------------------------------------------------------------------- itcl::class LocalsWin { inherit EmbeddedWin GDBWin # ------------------------------------------------------------------ # CONSTRUCTOR - create new locals window # ------------------------------------------------------------------ constructor {args} { debug gdbtk_busy build_win $itk_interior gdbtk_idle add_hook gdb_no_inferior_hook "$this no_inferior" add_hook gdb_clear_file_hook [code $this clear_file] add_hook file_changed_hook [code $this clear_file] update dummy } # ------------------------------------------------------------------ # PUBLIC METHOD: busy - BusyEvent handler # Disable all ui elements that could affect gdb's state # ------------------------------------------------------------------ method busy {event} { debug set Running 1 cursor watch } # Re-enable the UI method idle {event} { debug set Running 0 cursor {} } # ------------------------------------------------------------------ # METHOD: no_inferior # Reset this object. # ------------------------------------------------------------------ method no_inferior {} { debug cursor {} set Running 0 set _frame {} } # ------------------------------------------------------------------ # METHOD: cursor - change the toplevel's cursor # ------------------------------------------------------------------ method cursor {what} { [winfo toplevel [namespace tail $this]] configure -cursor $what ::update idletasks } # ------------------------------------------------------------------ # METHOD: build_win - build window for variables. # ------------------------------------------------------------------ method build_win {f} { #debug "$f" set tree [VarTree $f.tree -type "local"] pack $f.tree -expand yes -fill both pack $f -expand yes -fill both window_name "Local Variables" ::update idletasks } # ------------------------------------------------------------------ # METHOD: clear_file - Clear out state so that a new executable # can be loaded. For LocalWins, this means deleting # the Variables list. # ------------------------------------------------------------------ method clear_file {} { debug set Variables {} } # ------------------------------------------------------------------ # DESTRUCTOR - delete locals window # ------------------------------------------------------------------ destructor { debug set tree {} # Remove this window and all hooks remove_hook gdb_no_inferior_hook "$this no_inferior" remove_hook gdb_clear_file_hook [code $this clear_file] remove_hook file_changed_hook [code $this clear_file] foreach var $Variables { $var delete } } method context_switch {} { debug set err [catch {gdb_selected_frame} current_frame] #debug "1: err=$err; _frame=\"$_frame\"; current_frame=\"$current_frame\"" if {$err && $_frame != ""} { # No current frame debug "no current frame" catch {destroy $_frame} set _frame {} return 1 } elseif {$current_frame == "" && $_frame == ""} { #debug "2" return 0 } elseif {$_frame == "" || $current_frame != [$_frame address]} { # We've changed frames. If we knew something about # the stack layout, we could be more intelligent about # destroying variables, but we don't know that here (yet). debug "switching to frame at $current_frame" # Destroy the old frame and create the new one catch {destroy $_frame} set _frame [Frame ::\#auto $current_frame] debug "created new frame: $_frame at [$_frame address]" return 1 } # Nothing changed #debug "3" return 0 } method update {event} { debug # Check that a context switch has not occured if {[context_switch]} { debug "CONTEXT SWITCH" # delete variables in tree $tree remove all set Variables {} if {$_frame != ""} { $tree add [$_frame variables] } } else { if {$_frame == ""} {return} # check for any new variables in the same frame $tree add [$_frame new] } after idle [code $tree update] } protected variable Entry protected variable Variables {} protected variable tree protected variable Running protected variable _frame {} }