# tkfbox.tcl --
#
# Implements the "TK" standard file selection dialog box. This
# dialog box is used on the Unix platforms whenever the tk_strictMotif
# flag is not set.
#
# The "TK" standard file selection dialog box is similar to the
# file selection dialog box on Win95(TM). The user can navigate
# the directories by clicking on the folder icons or by
# selectinf the "Directory" option menu. The user can select
# files by clicking on the file icons or by entering a filename
# in the "Filename:" entry.
#
# SCCS: @(#) tkfbox.tcl 1.4 96/08/28 22:17:21
#
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#----------------------------------------------------------------------
#
# I C O N L I S T
#
# This is a pseudo-widget that implements the icon list inside the
# tkFDialog dialog box.
#
#----------------------------------------------------------------------
# tkIconList --
#
# Creates an IconList widget.
#
upvar #0 $w data
}
# tkIconList_Config --
#
# Configure the widget variables of IconList, according to the command
# line arguments.
#
upvar #0 $w data
# 1: the configuration specs
#
set specs {
{-browsecmd "" "" ""}
{-command "" "" ""}
}
# 2: parse the arguments
#
}
# tkIconList_Create --
#
# Creates an IconList widget by assembling a canvas widget and a
# scrollbar widget. Sets all the bindings necessary for the IconList's
# operations.
#
upvar #0 $w data
frame $w
#
# Creates the event bindings.
#
return $w
}
# tkIconList_AutoScan --
#
# This procedure is invoked when the mouse leaves an entry window
# with button 1 down. It scrolls the window up, down, left, or
# right, depending on where the mouse left the window, and reschedules
# itself as an "after" command so that the window continues to scroll until
# the mouse moves back into the window or the mouse button is released.
#
# Arguments:
# w - The IconList window.
#
upvar #0 $w data
global tkPriv
return
}
# do nothing
# do nothing
} else {
return
}
}
# Deletes all the items inside the canvas subwidget and reset the IconList's
# state.
#
upvar #0 $w data
upvar #0 $w:itemList itemList
catch {unset data(list)}
catch {unset itemList}
}
# Adds an icon into the IconList with the designated image and text
#
upvar #0 $w data
upvar #0 $w:itemList itemList
upvar #0 $w:textList textList
}
}
}
}
}
# Places the icons in a column-major arrangement.
#
upvar #0 $w data
}
return
}
} else {
}
set usedColumn 0
set usedColumn 1
set usedColumn 0
}
}
if {$usedColumn} {
} else {
}
} else {
}
}
}
}
# Gets called when the user invokes the IconList (usually by double-clicking
# or pressing the Return key).
#
upvar #0 $w data
}
}
# tkIconList_See --
#
# If the item is not (completely) visible, scroll the canvas so that
# it becomes visible.
upvar #0 $w data
upvar #0 $w:itemList itemList
return
}
return
}
return
}
# check if out of the right edge
#
}
# check if out of the left edge
#
}
}
}
upvar #0 $w data
}
upvar #0 $w data
upvar #0 $w:itemList itemList
return
}
-fill #a0a0ff -outline #a0a0ff]
}
if {$callBrowse} {
}
}
}
upvar #0 $w data
}
}
}
# Returns the selected item
#
upvar #0 $w data
} else {
return ""
}
}
upvar #0 $w data
focus $data(canvas)
}
# Gets called on button-1 motions
#
global tkPriv
}
upvar #0 $w data
}
}
}
global tkPriv
}
upvar #0 $w data
return
}
}
}
# tkIconList_UpDown --
#
# Moves the active element up or down by one element
#
# Arguments:
# w - The IconList widget.
# amount - +1 to move down one item, -1 to move back one item.
#
upvar #0 $w data
return
}
} else {
}
}
}
}
# tkIconList_LeftRight --
#
# Moves the active element left or right by one column
#
# Arguments:
# w - The IconList widget.
# amount - +1 to move right one column, -1 to move left one column.
#
upvar #0 $w data
return
}
} else {
}
}
}
}
#----------------------------------------------------------------------
# Accelerator key bindings
#----------------------------------------------------------------------
# tkIconList_KeyPress --
#
# Gets called when user enters an arbitrary key in the listbox.
#
global tkPriv
catch {
}
}
upvar #0 $w data
upvar #0 $w:textList textList
global tkPriv
return
}
return
}
} else {
}
set text [string tolower $text]
# Search forward until we find a filename whose prefix is an exact match
# with $text
while 1 {
break
}
incr i
}
break
}
}
}
}
global tkPriv
}
#----------------------------------------------------------------------
#
# F I L E D I A L O G
#
#----------------------------------------------------------------------
# tkFDialog --
#
# Implements the TK file selection dialog. This dialog is used when
# the tk_strictMotif flag is set to false. This procedure shouldn't
# be called directly. Call tk_getOpenFile or tk_getSaveFile instead.
#
global tkPriv
set w .__tk_filedialog
upvar #0 $w data
set type open
} else {
}
# (re)create the dialog box if necessary
#
destroy $w
}
# 5. Initialize the file types menu
#
}
} else {
}
# 6. Withdraw the window, then update all the geometry information
# so we know how big it wants to be, then center the window in the
# display and de-iconify it.
update idletasks
# 7. Set a grab and claim the focus too.
set oldFocus [focus]
}
grab $w
# 8. Wait for the user to respond, then restore the focus and
# return the index of the selected button. Restore the focus
# before deleting the window, since otherwise the window manager
# may take the focus away so we can't redirect it. Finally,
# restore any grab that was in effect.
tkwait variable tkPriv(selectFilePath)
catch {focus $oldFocus}
grab -global $oldGrab
} else {
grab $oldGrab
}
}
return $tkPriv(selectFilePath)
}
# tkFDialog_Config --
#
# Configures the TK filedialog according to the argument list
#
upvar #0 $w data
# 1: the configuration specs
#
set specs {
{-defaultextension "" "" ""}
{-filetypes "" "" ""}
{-initialdir "" "" ""}
{-initialfile "" "" ""}
{-parent "" "" "."}
{-title "" "" ""}
}
# 2: default values depending on the type of the dialog
#
# first time the dialog has been popped up
set data(selectPath) [pwd]
}
# 3: parse the arguments
#
} else {
}
}
# 4: set the default directory and selection according to the -initial
# settings
#
} else {
error "\"$data(-initialdir)\" is not a valid directory"
}
}
# 5. Parse the -filetypes option
#
error "bad window path name \"$data(-parent)\""
}
}
# Get image files from the library directory.
#
global tk_library env
if [info exists tk_library] {
if [file exists [file join $tk_library $file]] {
return [file join $tk_library $file]
}
}
return $file
}
upvar #0 $w data
global tk_library
# f1: the frame with the directory option menu
#
# data(icons): the IconList that list the files and directories.
#
-browsecmd "tkFDialog_ListBrowse $w" \
-command "tkFDialog_ListInvoke $w"]
# f2: the frame with the OK button and the "file name" field
#
# f3: the frame with the cancel button and the file types field
#
# the okBtn is created after the typeMenu so that the keyboard traversal
# is in the right order
# pack the widgets in f2 and f3
#
# Pack all the frames together. We are done with widget construction.
#
# Set up the event handlers
#
# Build the focus group for all the entries
#
}
# tkFDialog_UpdateWhenIdle --
#
# Creates an idle event handler which updates the dialog in idle
# time. This is important because loading the directory may take a long
# time and we don't want to load the same directory for multiple times
# due to multiple concurrent events.
#
upvar #0 $w data
return
} else {
}
}
# tkFDialog_Update --
#
# Loads the files and directories into the IconList widget. Also
# sets up the directory option menu for quick access to parent
# directories.
#
upvar #0 $w data
global tk_library tkPriv
# This proc may be called within an idle handler. Make sure that the
# window has not been destroyed before this proc is called
return
} else {
}
set tkPriv(folderImage) \
}
set appPWD [pwd]
if [catch {
cd $data(selectPath)
}] {
# We cannot change directory to $data(selectPath). $data(selectPath)
# should have been checked before tkFDialog_Update is called, so
# we normally won't come to here. Anyways, give an error and abort
# action.
"Cannot change to the directory \"$data(selectPath)\".\nPermission denied."\
cd $appPWD
return
}
# Turn on the busy cursor. BUG?? We haven't disabled X events, though,
# so the user may still click and cause havoc ...
#
update idletasks
# Make the dir list
#
continue
}
continue
}
}
}
}
# Make the file list
#
[glob -nocomplain .* *]]
} else {
}
}
}
}
# Update the Directory: option menu
#
set list ""
set dir ""
lappend list $dir
}
foreach path $list {
}
# Restore the PWD to the application's PWD
#
cd $appPWD
# turn off the busy cursor.
#
}
# tkFDialog_SetPathSilently --
#
# Sets data(selectPath) without invoking the trace procedure
#
upvar #0 $w data
}
# This proc gets called whenever data(selectPath) is set
#
upvar #0 $w data
}
# This proc gets called whenever data(filter) is set
#
upvar #0 $w data
upvar \#0 $data(icons) icons
}
# tkFDialogResolveFile --
#
# Interpret the user's text input in a file selection dialog.
# Performs:
#
# (1) ~ substitution
# (2) resolve all instances of . and ..
# (3) check for non-existent files/directories
# (4) check for chdir permissions
#
# Arguments:
# context: the current directory you are in
# text: the text entered by the user
#
# Return vaue:
# [list $flag $directory $file]
#
# flag = OK : valid input
# = PATH : the directory does not exist
# = FILE : the directory exists by the file doesn't
# exist
# = CHDIR : Cannot change to the directory
# = ERROR : Invalid entry
#
# directory : valid only if flag = OK or PATTERN or FILE
# file : valid only if flag = OK or PATTERN
#
# directory may not be the same as context, because text may contain
# a subdirectory name
#
set appPWD [pwd]
}
if [file isdirectory $path] {
if [catch {
cd $path
}] {
}
set directory [pwd]
set file ""
cd $appPWD
} else {
if [catch {
}] {
}
set directory [pwd]
cd $appPWD
}
} else {
if [catch {
cd $dirname
}] {
}
set directory [pwd]
if [regexp {[*]|[?]} $file] {
} else {
}
cd $appPWD
} else {
}
}
}
# Gets called when the entry box gets keyboard focus. We clear the selection
# from the icon list . This way the user can be certain that the input in the
# entry box is the selection.
#
upvar #0 $w data
} else {
}
} else {
}
}
upvar #0 $w data
}
# Gets called when user presses Return in the "File name" entry.
#
upvar #0 $w data
set file [lindex $list 2]
OK {
if ![string compare $file ""] {
# user has entered an existing (sub)directory
} else {
set data(selectFile) $file
}
}
PATTERN {
}
FILE {
-message "File \"[file join $path $file]\" does not exist."
} else {
set data(selectFile) $file
}
}
PATH {
-message "Directory \"$path\" does not exist."
}
CHDIR {
"Cannot change to the directory \"$path\".\nPermission denied."\
}
ERROR {
"Invalid file name \"$path\"."\
}
}
}
# Gets called when user presses the Alt-s or Alt-o keys.
#
upvar #0 $w data
}
}
# Gets called when user presses the "parent directory" button
#
upvar #0 $w data
}
}
# Gets called when user presses the "OK" button
#
upvar #0 $w data
if [string compare $text ""] {
set file [file join $data(selectPath) $text]
if [file isdirectory $file] {
tkFDialog_ListInvoke $w $text
return
}
}
}
# Gets called when user presses the "Cancel" button
#
upvar #0 $w data
global tkPriv
}
# Gets called when user browses the IconList widget (dragging mouse, arrow
# keys, etc)
#
upvar #0 $w data
if {$text == ""} {
return
}
set file [file join $data(selectPath) $text]
if ![file isdirectory $file] {
} else {
}
} else {
}
}
# Gets called when user invokes the IconList widget (double-click,
# Return key, etc)
#
upvar #0 $w data
if {$text == ""} {
return
}
set file [file join $data(selectPath) $text]
if [file isdirectory $file] {
set appPWD [pwd]
if [catch {cd $file}] {
"Cannot change to the directory \"$file\".\nPermission denied."\
} else {
cd $appPWD
set data(selectPath) $file
}
} else {
set data(selectFile) $file
}
}
# tkFDialog_Done --
#
# Gets called when user has input a valid filename. Pops up a
# dialog box to confirm selection when necessary. Sets the
# tkPriv(selectFilePath) variable, which will break the "tkwait"
# loop in tkFDialog and return the selected filename to the
# script that calls tk_getOpenFile or tk_getSaveFile
#
upvar #0 $w data
global tkPriv
if {[file exists $selectFilePath] &&
-message "File \"$selectFilePath\" already exists.\nDo you want to overwrite it?"]
return
}
}
}
}