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.
420 lines
13 KiB
Plaintext
420 lines
13 KiB
Plaintext
15 years ago
|
# Managed window for Insight.
|
||
|
# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2008 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.
|
||
|
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC METHOD: constructor
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::constructor {args} {
|
||
|
#debug "$this args=$args"
|
||
|
set _top [winfo toplevel $itk_interior]
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC METHOD: destructor
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::destructor {} {
|
||
|
# If no toplevels remain, quit. However, check the quit_if_last
|
||
|
# flag since we might be doing something like displaying a
|
||
|
# splash screen at startup...
|
||
|
|
||
|
if {!$numTopWins && [quit_if_last]} {
|
||
|
if {$::iipc && [pref get gdb/ipc/exit]} {
|
||
|
$::insight_ipc send quit
|
||
|
}
|
||
|
gdb_force_quit
|
||
|
} else {
|
||
|
destroy_toplevel
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC METHOD: window_name - Set the name of the window
|
||
|
# (and optionally its icon's name).
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::window_name {wname {iname ""}} {
|
||
|
|
||
|
if {$wname != ""} {
|
||
|
set _wname $wname
|
||
|
} else {
|
||
|
set wname $_wname
|
||
|
}
|
||
|
if {$iname != ""} {
|
||
|
set _iname $iname
|
||
|
} else {
|
||
|
set iname $_iname
|
||
|
}
|
||
|
|
||
|
if {$win_instance != ""} {
|
||
|
append wname " \[$win_instance\]"
|
||
|
if {$iname != ""} {
|
||
|
append iname " \[$win_instance\]"
|
||
|
}
|
||
|
}
|
||
|
wm title $_top $wname
|
||
|
if {$iname != ""} {
|
||
|
wm iconname $_top $iname
|
||
|
} else {
|
||
|
wm iconname $_top $wname
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC METHOD: window_instance - Set the string to be
|
||
|
# appended to each window title for this instance of Insight
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::window_instance {ins} {
|
||
|
set win_instance $ins
|
||
|
foreach obj [itcl_info objects -isa ManagedWin] {
|
||
|
debug "$obj ManagedWin::_wname"
|
||
|
$obj window_name ""
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC METHOD: pickle - This is the base class pickle
|
||
|
# method. It returns a command that can be used to recreate
|
||
|
# this particular window.
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::pickle {} {
|
||
|
return [list ManagedWin::open [namespace tail [info class]]]
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC METHOD: reveal
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::reveal {} {
|
||
|
# Do this update to flush all changes before deiconifying the window.
|
||
|
update idletasks
|
||
|
|
||
|
raise $_top
|
||
|
wm deiconify $_top
|
||
|
|
||
|
# Some window managers (on unix) fail to honor the geometry unless
|
||
|
# the window is visible.
|
||
|
if {[info exists ::$_top._init_geometry]} {
|
||
|
upvar ::$_top._init_geometry gm
|
||
|
if {$::gdbtk_platform(platform) == "unix"} {
|
||
|
wm geometry $_top $gm
|
||
|
}
|
||
|
unset ::$_top._init_geometry
|
||
|
}
|
||
|
|
||
|
# There used to be a `focus -force' here, but using -force is
|
||
|
# unfriendly, so it was removed. It was then replaced with a simple
|
||
|
# `focus $top'. However, this has no useful effect -- it just
|
||
|
# resets the subwindow of $top which has the `potential' focus.
|
||
|
# This can actually be confusing to the user.
|
||
|
|
||
|
# NOT for Windows, though. Without the focus, we get, eg. a
|
||
|
# register window on top of the source window, but the source window
|
||
|
# will have the focus. This is not the proper model for Windows.
|
||
|
if {$::gdbtk_platform(platform) == "windows"} {
|
||
|
focus -force [focus -lastfor $_top]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC PROC: restart
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::restart {} {
|
||
|
# This is needed in case we've called "gdbtk_busy" before the restart.
|
||
|
# This will configure the stop/run button as necessary
|
||
|
after idle gdbtk_idle
|
||
|
|
||
|
# call the reconfig method for each object
|
||
|
foreach obj [itcl_info objects -isa ManagedWin] {
|
||
|
if {[catch {$obj reconfig} msg]} {
|
||
|
dbug W "reconfig failed for $obj - $msg"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
# PUBLIC PROC: shutdown - This writes all the active windows to
|
||
|
# the preferences file, so they can be restored at startup.
|
||
|
# FIXME: Currently assumes only ONE window per type...
|
||
|
# ------------------------------------------------------------------
|
||
|
itcl::body ManagedWin::shutdown {} {
|
||
|
set activeWins {}
|
||
|
foreach win [itcl_info objects -isa ManagedWin] {
|
||
|
if {![$win isa ModalDialog] && ![$win _ignore_on_save]} {
|
||
|
set g [wm geometry [winfo toplevel [namespace tail $win]]]
|
||
|
pref setd gdb/geometry/[namespace tail $win] $g
|
||
|
lappend activeWins [$win pickle]
|
||
|
}
|
||
|
}
|
||
|
pref set gdb/window/active $activeWins
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
# PUBLIC PROC: startup - This restores all the windows that were
|
||
|
# opened at shutdown.
|
||
|
# FIXME: Currently assumes only ONE window per type...
|
||
|
# ------------------------------------------------------------------
|
||
|
itcl::body ManagedWin::startup {} {
|
||
|
debug "Got active list [pref get gdb/window/active]"
|
||
|
|
||
|
foreach cmd [pref get gdb/window/active] {
|
||
|
eval $cmd
|
||
|
}
|
||
|
# If we open the source window, and a source window already exists,
|
||
|
# then we end up raising it twice during startup. This yields an
|
||
|
# annoying effect for the user: if the user tries the bury the
|
||
|
# source window during startup, it will raise itself again. This
|
||
|
# explains why we first check to see if a source window exists
|
||
|
# before trying to create it -- raising the window is an inevitable
|
||
|
# side effect of the creation process.
|
||
|
if {[llength [find SrcWin]] == 0} {
|
||
|
ManagedWin::open SrcWin
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC PROC: open_dlg
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::open_dlg {class args} {
|
||
|
|
||
|
set newwin [eval _open $class $args]
|
||
|
if {$newwin != ""} {
|
||
|
$newwin reveal
|
||
|
$newwin post
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC PROC: open
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::open {class args} {
|
||
|
|
||
|
set newwin [eval _open $class $args]
|
||
|
if {$newwin != ""} {
|
||
|
if {[$newwin isa ModalDialog]} {
|
||
|
parse_args [list {expire 0}]
|
||
|
after idle "$newwin reveal; $newwin post 0 $expire"
|
||
|
} else {
|
||
|
after idle "$newwin reveal"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $newwin
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PRIVATE PROC: _open
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::_open { class args } {
|
||
|
debug "$class $args"
|
||
|
|
||
|
parse_args force
|
||
|
|
||
|
if {!$force} {
|
||
|
# check all windows for one of this type
|
||
|
foreach obj [itcl_info objects -isa ManagedWin] {
|
||
|
if {[$obj isa $class]} {
|
||
|
$obj reveal
|
||
|
return $obj
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
# need to create a new window
|
||
|
return [eval _create $class $args]
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PRIVATE PROC: _create
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::_create { class args } {
|
||
|
|
||
|
set win [string tolower $class]
|
||
|
debug "win=$win args=$args"
|
||
|
|
||
|
parse_args {center transient {over ""}}
|
||
|
|
||
|
# increment window numbers until we get an unused one
|
||
|
set i 0
|
||
|
while {[winfo exists .$win$i]} { incr i }
|
||
|
|
||
|
while { 1 } {
|
||
|
set top [toplevel .$win$i]
|
||
|
wm withdraw $top
|
||
|
wm protocol $top WM_DELETE_WINDOW "destroy $top"
|
||
|
wm group $top .
|
||
|
set newwin $top.$win
|
||
|
if {[catch {uplevel \#0 eval $class $newwin $args} msg]} {
|
||
|
dbug E "object creation of $class failed: $msg"
|
||
|
dbug E $::errorInfo
|
||
|
if {[string first "object already exists" $msg] != -1} {
|
||
|
# sometimes an object is still really around even though
|
||
|
# [winfo exists] said it didn't exist. Check for this case
|
||
|
# and increment the window number again.
|
||
|
catch {destroy $top}
|
||
|
incr i
|
||
|
} else {
|
||
|
return ""
|
||
|
}
|
||
|
} else {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if {[catch {pack $newwin -expand yes -fill both}]} {
|
||
|
dbug W "packing of $newwin failed: $::errorInfo"
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
wm maxsize $top $_screenwidth $_screenheight
|
||
|
wm minsize $top 20 20
|
||
|
update idletasks
|
||
|
|
||
|
if {$over != ""} {
|
||
|
# center new window
|
||
|
center_window $top -over [winfo toplevel [namespace tail $over]]
|
||
|
} elseif {$center} {
|
||
|
center_window $top
|
||
|
}
|
||
|
|
||
|
if {$transient} {
|
||
|
wm resizable $top 0 0
|
||
|
|
||
|
# If a SrcWin is around, use its toplevel as the master for
|
||
|
# the transient. Otherwise use ".". (The splash screen will
|
||
|
# need ".", for example.)
|
||
|
set srcs [ManagedWin::find SrcWin]
|
||
|
if {[llength $srcs] > 0} {
|
||
|
set w [winfo toplevel [namespace tail [lindex $srcs 0]]]
|
||
|
} else {
|
||
|
set w .
|
||
|
}
|
||
|
wm transient $top $w
|
||
|
} elseif {$::gdbtk_platform(platform) == "unix"} {
|
||
|
# Modal dialogs DONT get Icons...
|
||
|
if {[pref get gdb/use_icons] && ![$newwin isa ModalDialog]} {
|
||
|
set icon [_make_icon_window ${top}_icon]
|
||
|
wm iconwindow $top $icon
|
||
|
bind $icon <Double-1> "$newwin reveal"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if {[info exists ::env(GDBTK_TEST_RUNNING)] && $::env(GDBTK_TEST_RUNNING)} {
|
||
|
set g "+100+100"
|
||
|
wm geometry $top $g
|
||
|
wm positionfrom $top user
|
||
|
} else {
|
||
|
set g [pref getd gdb/geometry/$newwin]
|
||
|
if {$g == "1x1+0+0"} {
|
||
|
dbug E "bad geometry"
|
||
|
set g ""
|
||
|
}
|
||
|
if {$g != ""} {
|
||
|
# OK. We have a requested geometry. We know that it fits on the screen
|
||
|
# because we set the maxsize. Now we have to make sure it will not be
|
||
|
# displayed off the screen.
|
||
|
set w 0; set h 0; set x 0; set y 0
|
||
|
if {![catch {scan $g "%dx%d%d%d" w h x y} res]} {
|
||
|
if {$x < 0} {
|
||
|
set x [expr $_screenwidth + $x]
|
||
|
}
|
||
|
if {$y < 0} {
|
||
|
set y [expr $_screenheight + $y]
|
||
|
}
|
||
|
|
||
|
# If the window is transient, then don't reset its size, since
|
||
|
# the user didn't set this anyway, and in some cases where the
|
||
|
# size can change dynamically, like the Global Preferences
|
||
|
# dialog, this can hide parts of the dialog with no recourse...
|
||
|
|
||
|
# if dont_remember_size is true, don't set size, just like
|
||
|
# transients
|
||
|
|
||
|
if {$transient || [dont_remember_size]} {
|
||
|
set g "+${x}+${y}"
|
||
|
} else {
|
||
|
set g "${w}x${h}+${x}+${y}"
|
||
|
}
|
||
|
if {[expr $x+50] < $_screenwidth && [expr $y+20] < $_screenheight} {
|
||
|
wm positionfrom $top user
|
||
|
wm geometry $top $g
|
||
|
set ::$top._init_geometry $g
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bind $top <Alt-F4> [list delete object $newwin]
|
||
|
|
||
|
return $newwin
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC PROC: find
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::find { win } {
|
||
|
debug "$win"
|
||
|
set res ""
|
||
|
foreach obj [itcl_info objects -isa ManagedWin] {
|
||
|
if {[$obj isa $win]} {
|
||
|
lappend res $obj
|
||
|
}
|
||
|
}
|
||
|
return $res
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC PROC: init
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::init {} {
|
||
|
wm withdraw .
|
||
|
set _screenheight [winfo screenheight .]
|
||
|
set _screenwidth [winfo screenwidth .]
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PUBLIC METHOD: destroy_toplevel
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::destroy_toplevel {} {
|
||
|
after idle "update idletasks;destroy $_top"
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PROTECTED METHOD: _freeze_me
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::_freeze_me {} {
|
||
|
$_top configure -cursor watch
|
||
|
::update idletasks
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# PROTECTED METHOD: _thaw_me
|
||
|
# ------------------------------------------------------------
|
||
|
itcl::body ManagedWin::_thaw_me {} {
|
||
|
|
||
|
$_top configure -cursor {}
|
||
|
::update idletasks
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------------
|
||
|
# PRIVATE PROC: _make_icon_window - create a small window with an
|
||
|
# icon in it for use by certain Unix window managers.
|
||
|
# ------------------------------------------------------------------
|
||
|
itcl::body ManagedWin::_make_icon_window {name {file "gdbtk_icon"}} {
|
||
|
if {![winfo exists $name]} {
|
||
|
toplevel $name
|
||
|
label $name.im -image \
|
||
|
[image create photo icon_photo -file [file join $::gdb_ImageDir $file.gif]]
|
||
|
}
|
||
|
pack $name.im
|
||
|
return $name
|
||
|
}
|