summaryrefslogtreecommitdiff
path: root/iwidgets/generic/fileselectionbox.itk
diff options
context:
space:
mode:
Diffstat (limited to 'iwidgets/generic/fileselectionbox.itk')
-rw-r--r--iwidgets/generic/fileselectionbox.itk1296
1 files changed, 1296 insertions, 0 deletions
diff --git a/iwidgets/generic/fileselectionbox.itk b/iwidgets/generic/fileselectionbox.itk
new file mode 100644
index 00000000000..b083c5020b7
--- /dev/null
+++ b/iwidgets/generic/fileselectionbox.itk
@@ -0,0 +1,1296 @@
+#
+# Fileselectionbox
+# ----------------------------------------------------------------------
+# Implements a file selection box in a style similar to the OSF/Motif
+# standard XmFileselectionbox composite widget. The Fileselectionbox
+# is composed of directory and file scrolled lists as well as filter
+# and selection entry fields.
+#
+# ----------------------------------------------------------------------
+# AUTHOR: Mark L. Ulferts EMAIL: mulferts@spd.dsccc.com
+#
+# @(#) $Id$
+# ----------------------------------------------------------------------
+# Copyright (c) 1997 DSC Technologies Corporation
+# ======================================================================
+# Permission to use, copy, modify, distribute and license this software
+# and its documentation for any purpose, and without fee or written
+# agreement with DSC, is hereby granted, provided that the above copyright
+# notice appears in all copies and that both the copyright notice and
+# warranty disclaimer below appear in supporting documentation, and that
+# the names of DSC Technologies Corporation or DSC Communications
+# Corporation not be used in advertising or publicity pertaining to the
+# software without specific, written prior permission.
+#
+# DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
+# INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
+# AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL
+# DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
+# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+# ======================================================================
+
+#
+# Usual options.
+#
+itk::usual Fileselectionbox {
+ keep -activebackground -activerelief -background -borderwidth -cursor \
+ -elementborderwidth -foreground -highlightcolor -highlightthickness \
+ -insertbackground -insertborderwidth -insertofftime -insertontime \
+ -insertwidth -jump -labelfont -selectbackground -selectborderwidth \
+ -textbackground -textfont -troughcolor
+}
+
+# ------------------------------------------------------------------
+# FILESELECTIONBOX
+# ------------------------------------------------------------------
+itcl::class iwidgets::Fileselectionbox {
+ inherit itk::Widget
+
+ constructor {args} {}
+ destructor {}
+
+ itk_option define -childsitepos childSitePos Position s
+ itk_option define -fileson filesOn FilesOn true
+ itk_option define -dirson dirsOn DirsOn true
+ itk_option define -selectionon selectionOn SelectionOn true
+ itk_option define -filteron filterOn FilterOn true
+ itk_option define -mask mask Mask {*}
+ itk_option define -directory directory Directory {}
+ itk_option define -automount automount Automount {}
+ itk_option define -nomatchstring noMatchString NoMatchString {}
+ itk_option define -dirsearchcommand dirSearchCommand Command {}
+ itk_option define -filesearchcommand fileSearchCommand Command {}
+ itk_option define -selectioncommand selectionCommand Command {}
+ itk_option define -filtercommand filterCommand Command {}
+ itk_option define -selectdircommand selectDirCommand Command {}
+ itk_option define -selectfilecommand selectFileCommand Command {}
+ itk_option define -invalid invalid Command {bell}
+ itk_option define -filetype fileType FileType {regular}
+ itk_option define -width width Width 350
+ itk_option define -height height Height 300
+
+ public {
+ method childsite {}
+ method get {}
+ method filter {}
+ }
+
+ public {
+ method _selectDir {}
+ method _dblSelectDir {}
+ method _selectFile {}
+ method _selectSelection {}
+ method _selectFilter {}
+ }
+
+ protected {
+ method _packComponents {{when later}}
+ method _updateLists {{when later}}
+ }
+
+ private {
+ method _setFilter {}
+ method _setSelection {}
+ method _setDirList {}
+ method _setFileList {}
+
+ method _nPos {}
+ method _sPos {}
+ method _ePos {}
+ method _wPos {}
+ method _topPos {}
+ method _centerPos {}
+ method _bottomPos {}
+
+ variable _packToken "" ;# non-null => _packComponents pending
+ variable _updateToken "" ;# non-null => _updateLists pending
+ variable _pwd "." ;# present working dir
+ variable _interior ;# original interior setting
+ }
+}
+
+#
+# Provide a lowercased access method for the Fileselectionbox class.
+#
+proc ::iwidgets::fileselectionbox {pathName args} {
+ uplevel ::iwidgets::Fileselectionbox $pathName $args
+}
+
+#
+# Use option database to override default resources of base classes.
+#
+option add *Fileselectionbox.borderWidth 2 widgetDefault
+
+option add *Fileselectionbox.filterLabel Filter widgetDefault
+option add *Fileselectionbox.dirsLabel Directories widgetDefault
+option add *Fileselectionbox.filesLabel Files widgetDefault
+option add *Fileselectionbox.selectionLabel Selection widgetDefault
+
+option add *Fileselectionbox.width 350 widgetDefault
+option add *Fileselectionbox.height 300 widgetDefault
+
+# ------------------------------------------------------------------
+# CONSTRUCTOR
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::constructor {args} {
+ #
+ # Add back to the hull width and height options and make the
+ # borderwidth zero since we don't need it.
+ #
+ itk_option add hull.width hull.height
+ component hull configure -borderwidth 0
+
+ set _interior $itk_interior
+
+ #
+ # Create the filter entry.
+ #
+ itk_component add filter {
+ iwidgets::Entryfield $itk_interior.filter -labelpos nw \
+ -command [itcl::code $this _selectFilter] -exportselection 0
+ } {
+ usual
+
+ rename -labeltext -filterlabel filterLabel Text
+ }
+
+ #
+ # Create the directory list.
+ #
+ itk_component add dirs {
+ iwidgets::Scrolledlistbox $itk_interior.dirs \
+ -selectioncommand [itcl::code $this _selectDir] \
+ -selectmode single -exportselection 0 \
+ -visibleitems 1x1 -labelpos nw \
+ -hscrollmode static -vscrollmode static \
+ -dblclickcommand [itcl::code $this _dblSelectDir]
+ } {
+ usual
+
+ rename -labeltext -dirslabel dirsLabel Text
+ }
+
+ #
+ # Create the files list.
+ #
+ itk_component add files {
+ iwidgets::Scrolledlistbox $itk_interior.files \
+ -selectioncommand [itcl::code $this _selectFile] \
+ -selectmode single -exportselection 0 \
+ -visibleitems 1x1 -labelpos nw \
+ -hscrollmode static -vscrollmode static
+ } {
+ usual
+
+ rename -labeltext -fileslabel filesLabel Text
+ }
+
+ #
+ # Create the selection entry.
+ #
+ itk_component add selection {
+ iwidgets::Entryfield $itk_interior.selection -labelpos nw \
+ -command [itcl::code $this _selectSelection] -exportselection 0
+ } {
+ usual
+
+ rename -labeltext -selectionlabel selectionLabel Text
+ }
+
+ #
+ # Create the child site widget.
+ #
+ itk_component add -protected childsite {
+ frame $itk_interior.fsbchildsite
+ }
+
+ #
+ # Set the interior variable to the childsite for derived classes.
+ #
+ set itk_interior $itk_component(childsite)
+
+ #
+ # Explicitly handle configs that may have been ignored earlier.
+ #
+ eval itk_initialize $args
+
+ #
+ # When idle, pack the childsite and update the lists.
+ #
+ _packComponents
+ _updateLists
+}
+
+# ------------------------------------------------------------------
+# DESTRUCTOR
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::destructor {} {
+ if {$_packToken != ""} {after cancel $_packToken}
+ if {$_updateToken != ""} {after cancel $_updateToken}
+}
+
+# ------------------------------------------------------------------
+# OPTIONS
+# ------------------------------------------------------------------
+
+# ------------------------------------------------------------------
+# OPTION: -childsitepos
+#
+# Specifies the position of the child site in the selection box.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::childsitepos {
+ _packComponents
+}
+
+# ------------------------------------------------------------------
+# OPTION: -fileson
+#
+# Specifies whether or not to display the files list.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::fileson {
+ _packComponents
+}
+
+# ------------------------------------------------------------------
+# OPTION: -dirson
+#
+# Specifies whether or not to display the dirs list.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::dirson {
+ _packComponents
+}
+
+# ------------------------------------------------------------------
+# OPTION: -selectionon
+#
+# Specifies whether or not to display the selection entry widget.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::selectionon {
+ _packComponents
+}
+
+# ------------------------------------------------------------------
+# OPTION: -filteron
+#
+# Specifies whether or not to display the filter entry widget.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::filteron {
+ _packComponents
+}
+
+# ------------------------------------------------------------------
+# OPTION: -mask
+#
+# Specifies the initial file mask string.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::mask {
+ global tcl_platform
+ set prefix $_pwd
+
+ #
+ # Remove automounter paths.
+ #
+ if {$tcl_platform(platform) == "unix"} {
+ if {$itk_option(-automount) != {}} {
+ foreach autoDir $itk_option(-automount) {
+ # Use catch because we can't be sure exactly what strings
+ # were passed into the -automount option
+ catch {
+ if {[regsub ^/$autoDir $prefix {} prefix] != 0} {
+ break
+ }
+ }
+ }
+ }
+ }
+
+ set curFilter $itk_option(-mask);
+ $itk_component(filter) delete 0 end
+ $itk_component(filter) insert 0 [file join $_pwd $itk_option(-mask)]
+
+ #
+ # Make sure the right most text is visable.
+ #
+ $itk_component(filter) xview moveto 1
+}
+
+# ------------------------------------------------------------------
+# OPTION: -directory
+#
+# Specifies the initial default directory.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::directory {
+ if {$itk_option(-directory) != {}} {
+ if {! [file exists $itk_option(-directory)]} {
+ error "bad directory option \"$itk_option(-directory)\":\
+ directory does not exist"
+ }
+
+ set olddir [pwd]
+ cd $itk_option(-directory)
+ set _pwd [pwd]
+ cd $olddir
+
+ configure -mask $itk_option(-mask)
+ _selectFilter
+ }
+}
+
+# ------------------------------------------------------------------
+# OPTION: -automount
+#
+# Specifies list of directory prefixes to ignore. Typically, this
+# option would be used with values such as:
+# -automount {export tmp_mnt}
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::automount {
+}
+
+# ------------------------------------------------------------------
+# OPTION: -nomatchstring
+#
+# Specifies the string to be displayed in the files list should
+# not regular files exist in the directory.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::nomatchstring {
+}
+
+# ------------------------------------------------------------------
+# OPTION: -dirsearchcommand
+#
+# Specifies a command to be executed to perform a directory search.
+# The command will receive the current working directory and filter
+# mask as arguments. The command should return a list of files which
+# will be placed into the directory list.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::dirsearchcommand {
+}
+
+# ------------------------------------------------------------------
+# OPTION: -filesearchcommand
+#
+# Specifies a command to be executed to perform a file search.
+# The command will receive the current working directory and filter
+# mask as arguments. The command should return a list of files which
+# will be placed into the file list.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::filesearchcommand {
+}
+
+# ------------------------------------------------------------------
+# OPTION: -selectioncommand
+#
+# Specifies a command to be executed upon pressing return in the
+# selection entry widget.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::selectioncommand {
+}
+
+# ------------------------------------------------------------------
+# OPTION: -filtercommand
+#
+# Specifies a command to be executed upon pressing return in the
+# filter entry widget.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::filtercommand {
+}
+
+# ------------------------------------------------------------------
+# OPTION: -selectdircommand
+#
+# Specifies a command to be executed following selection of a
+# directory in the directory list.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::selectdircommand {
+}
+
+# ------------------------------------------------------------------
+# OPTION: -selectfilecommand
+#
+# Specifies a command to be executed following selection of a
+# file in the files list.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::selectfilecommand {
+}
+
+# ------------------------------------------------------------------
+# OPTION: -invalid
+#
+# Specify a command to executed should the filter contents be
+# proven invalid.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::invalid {
+}
+
+# ------------------------------------------------------------------
+# OPTION: -filetype
+#
+# Specify the type of files which may appear in the file list.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::filetype {
+ switch $itk_option(-filetype) {
+ regular -
+ directory -
+ any {
+ }
+ default {
+ error "bad filetype option \"$itk_option(-filetype)\":\
+ should be regular, directory, or any"
+ }
+ }
+
+ _updateLists
+}
+
+# ------------------------------------------------------------------
+# OPTION: -width
+#
+# Specifies the width of the file selection box. The value may be
+# specified in any of the forms acceptable to Tk_GetPixels.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::width {
+ #
+ # The width option was added to the hull in the constructor.
+ # So, any width value given is passed automatically to the
+ # hull. All we have to do is play with the propagation.
+ #
+ if {$itk_option(-width) != 0} {
+ set propagate 0
+ } else {
+ set propagate 1
+ }
+
+ #
+ # Due to a bug in the tk4.2 grid, we have to check the
+ # propagation before setting it. Setting it to the same
+ # value it already is will cause it to toggle.
+ #
+ if {[grid propagate $itk_component(hull)] != $propagate} {
+ grid propagate $itk_component(hull) $propagate
+ }
+}
+
+# ------------------------------------------------------------------
+# OPTION: -height
+#
+# Specifies the height of the file selection box. The value may be
+# specified in any of the forms acceptable to Tk_GetPixels.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Fileselectionbox::height {
+ #
+ # The height option was added to the hull in the constructor.
+ # So, any height value given is passed automatically to the
+ # hull. All we have to do is play with the propagation.
+ #
+ if {$itk_option(-height) != 0} {
+ set propagate 0
+ } else {
+ set propagate 1
+ }
+
+ #
+ # Due to a bug in the tk4.2 grid, we have to check the
+ # propagation before setting it. Setting it to the same
+ # value it already is will cause it to toggle.
+ #
+ if {[grid propagate $itk_component(hull)] != $propagate} {
+ grid propagate $itk_component(hull) $propagate
+ }
+}
+
+# ------------------------------------------------------------------
+# METHODS
+# ------------------------------------------------------------------
+
+# ------------------------------------------------------------------
+# METHOD: childsite
+#
+# Returns the path name of the child site widget.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::childsite {} {
+ return $itk_component(childsite)
+}
+
+# ------------------------------------------------------------------
+# METHOD: get
+#
+# Returns the current selection.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::get {} {
+ return [$itk_component(selection) get]
+}
+
+# ------------------------------------------------------------------
+# METHOD: filter
+#
+# The user has pressed Return in the filter. Make sure the contents
+# contain a valid directory before setting default to directory.
+# Use the invalid option to warn the user of any problems.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::filter {} {
+ set newdir [file dirname [$itk_component(filter) get]]
+
+ if {! [file exists $newdir]} {
+ uplevel #0 "$itk_option(-invalid)"
+ return
+ }
+
+ set _pwd $newdir;
+ if {$_pwd == "."} {set _pwd [pwd]};
+
+ _updateLists
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _updateLists ?now?
+#
+# Updates the contents of both the file and directory lists, as well
+# resets the positions of the filter, and lists.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_updateLists {{when "later"}} {
+ switch -- $when {
+ later {
+ if {$_updateToken == ""} {
+ set _updateToken [after idle [itcl::code $this _updateLists now]]
+ }
+ }
+ now {
+ if {$itk_option(-dirson)} {_setDirList}
+ if {$itk_option(-fileson)} {_setFileList}
+
+ if {$itk_option(-filteron)} {
+ _setFilter
+ }
+ if {$itk_option(-selectionon)} {
+ $itk_component(selection) icursor end
+ }
+ if {$itk_option(-dirson)} {
+ $itk_component(dirs) justify left
+ }
+ if {$itk_option(-fileson)} {
+ $itk_component(files) justify left
+ }
+ set _updateToken ""
+ }
+ default {
+ error "bad option \"$when\": should be later or now"
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _setFilter
+#
+# Set the filter to the current selection in the directory list plus
+# any existing mask in the filter. Translate the two special cases
+# of '.', and '..' directory names to full path names..
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_setFilter {} {
+ global tcl_platform
+ set prefix [$itk_component(dirs) getcurselection]
+ set curFilter [file tail [$itk_component(filter) get]]
+
+ while {[regexp {\.$} $prefix]} {
+ if {[file tail $prefix] == "."} {
+ if {$prefix == "."} {
+ if {$_pwd == "."} {
+ set _pwd [pwd]
+ } elseif {$_pwd == ".."} {
+ set _pwd [file dirname [pwd]]
+ }
+ set prefix $_pwd
+ } else {
+ set prefix [file dirname $prefix]
+ }
+ } elseif {[file tail $prefix] == ".."} {
+ if {$prefix != ".."} {
+ set prefix [file dirname [file dirname $prefix]]
+ } else {
+ if {$_pwd == "."} {
+ set _pwd [pwd]
+ } elseif {$_pwd == ".."} {
+ set _pwd [file dirname [pwd]]
+ }
+ set prefix [file dirname $_pwd]
+ }
+ } else {
+ break
+ }
+ }
+
+ if { [file pathtype $prefix] != "absolute" } {
+ set prefix [file join $_pwd $prefix]
+ }
+
+ #
+ # Remove automounter paths.
+ #
+ if {$tcl_platform(platform) == "unix"} {
+ if {$itk_option(-automount) != {}} {
+ foreach autoDir $itk_option(-automount) {
+ # Use catch because we can't be sure exactly what strings
+ # were passed into the -automount option
+ catch {
+ if {[regsub ^/$autoDir $prefix {} prefix] != 0} {
+ break
+ }
+ }
+ }
+ }
+ }
+
+ $itk_component(filter) delete 0 end
+ $itk_component(filter) insert 0 [file join $prefix $curFilter]
+
+ #
+ # Make sure insertion cursor is at the end.
+ #
+ $itk_component(filter) icursor end
+
+ #
+ # Make sure the right most text is visable.
+ #
+ $itk_component(filter) xview moveto 1
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _setSelection
+#
+# Set the contents of the selection entry to either the current
+# selection of the file or directory list dependent on which lists
+# are currently mapped. For the file list, avoid seleciton of the
+# no match string. As for the directory list, translate file names.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_setSelection {} {
+ global tcl_platform
+ $itk_component(selection) delete 0 end
+
+ if {$itk_option(-fileson)} {
+ set selection [$itk_component(files) getcurselection]
+
+ if {$selection != $itk_option(-nomatchstring)} {
+ if {[file pathtype $selection] != "absolute"} {
+ set selection [file join $_pwd $selection]
+ }
+
+ #
+ # Remove automounter paths.
+ #
+ if {$tcl_platform(platform) == "unix"} {
+ if {$itk_option(-automount) != {}} {
+ foreach autoDir $itk_option(-automount) {
+ # Use catch because we can't be sure exactly what strings
+ # were passed into the -automount option
+ catch {
+ if {[regsub ^/$autoDir $selection {} selection] != 0} {
+ break
+ }
+ }
+ }
+ }
+ }
+
+ $itk_component(selection) insert 0 $selection
+ } else {
+ $itk_component(files) selection clear 0 end
+ }
+
+ } else {
+ set selection [$itk_component(dirs) getcurselection]
+
+ if {[file tail $selection] == "."} {
+ if {$selection != "."} {
+ set selection [file dirname $selection]
+ } else {
+ set selection $_pwd
+ }
+ } elseif {[file tail $selection] == ".."} {
+ if {$selection != ".."} {
+ set selection [file dirname [file dirname $selection]]
+ } else {
+ set selection [file join $_pwd ..]
+ }
+ } else {
+ set selection [file join $_pwd $selection]
+ }
+
+ #
+ # Remove automounter paths.
+ #
+ if {$tcl_platform(platform) == "unix"} {
+ if {$itk_option(-automount) != {}} {
+ foreach autoDir $itk_option(-automount) {
+ # Use catch because we can't be sure exactly what strings
+ # were passed into the -automount option
+ catch {
+ if {[regsub ^/$autoDir $selection {} selection] != 0} {
+ break
+ }
+ }
+ }
+ }
+ }
+
+ $itk_component(selection) delete 0 end
+ $itk_component(selection) insert 0 $selection
+ }
+
+ $itk_component(selection) icursor end
+
+ #
+ # Make sure the right most text is visable.
+ #
+ $itk_component(selection) xview moveto 1
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _setDirList
+#
+# Clear the directory list and dependent on whether the user has
+# defined their own search procedure or not fill the list with their
+# results or those of a glob. Select the first element if it exists.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_setDirList {} {
+ $itk_component(dirs) clear
+
+ if {$itk_option(-dirsearchcommand) == {}} {
+ foreach i [lsort [glob -nocomplain \
+ [file join $_pwd .*] [file join $_pwd *]]] {
+ if {[file isdirectory $i]} {
+ $itk_component(dirs) insert end [file tail "$i"]
+ }
+ }
+
+ } else {
+ set mask [file tail [$itk_component(filter) get]]
+
+ foreach file [uplevel #0 $itk_option(-dirsearchcommand) $_pwd $mask] {
+ $itk_component(dirs) insert end $file
+ }
+ }
+
+ if {[$itk_component(dirs) size]} {
+ $itk_component(dirs) selection clear 0 end
+ $itk_component(dirs) selection set 0
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _setFileList
+#
+# Clear the file list and dependent on whether the user has defined
+# their own search procedure or not fill the list with their results
+# or those of a 'glob'. If the files list has no contents, then set
+# the files list to the 'nomatchstring'. Clear all selections.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_setFileList {} {
+ $itk_component(files) clear
+ set mask [file tail [$itk_component(filter) get]]
+
+ if {$itk_option(-filesearchcommand) == {}} {
+ if {$mask == "*"} {
+ set files [lsort [glob -nocomplain \
+ [file join $_pwd .*] [file join $_pwd *]]]
+ } else {
+ set files [lsort [glob -nocomplain [file join $_pwd $mask]]]
+ }
+
+ foreach i $files {
+ if {($itk_option(-filetype) == "regular" && \
+ ! [file isdirectory $i]) || \
+ ($itk_option(-filetype) == "directory" && \
+ [file isdirectory $i]) || \
+ ($itk_option(-filetype) == "any")} {
+ $itk_component(files) insert end [file tail "$i"]
+ }
+ }
+
+ } else {
+ foreach file [uplevel #0 $itk_option(-filesearchcommand) $_pwd $mask] {
+ $itk_component(files) insert end $file
+ }
+ }
+
+ if {[$itk_component(files) size] == 0} {
+ if {$itk_option(-nomatchstring) != {}} {
+ $itk_component(files) insert end $itk_option(-nomatchstring)
+ }
+ }
+
+ $itk_component(files) selection clear 0 end
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _selectDir
+#
+# For a selection in the directory list, set the filter and possibly
+# the selection entry based on the fileson option.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_selectDir {} {
+ _setFilter
+
+ if {$itk_option(-fileson)} {} {
+ _setSelection
+ }
+
+ if {$itk_option(-selectdircommand) != {}} {
+ uplevel #0 $itk_option(-selectdircommand)
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _dblSelectDir
+#
+# For a double click event in the directory list, select the
+# directory, set the default to the selection, and update both the
+# file and directory lists.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_dblSelectDir {} {
+ filter
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _selectFile
+#
+# The user has selected a file. Put the current selection in the
+# file list in the selection entry widget.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_selectFile {} {
+ _setSelection
+
+ if {$itk_option(-selectfilecommand) != {}} {
+ uplevel #0 $itk_option(-selectfilecommand)
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _selectSelection
+#
+# The user has pressed Return in the selection entry widget. Call
+# the defined selection command if it exists.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_selectSelection {} {
+ if {$itk_option(-selectioncommand) != {}} {
+ uplevel #0 $itk_option(-selectioncommand)
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _selectFilter
+#
+# The user has pressed Return in the filter entry widget. Call the
+# defined selection command if it exists, otherwise just filter.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_selectFilter {} {
+ if {$itk_option(-filtercommand) != {}} {
+ uplevel #0 $itk_option(-filtercommand)
+ } else {
+ filter
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _packComponents
+#
+# Pack the selection, items, and child site widgets based on options.
+# Using the -in option of pack, put the childsite around the frame
+# in the hull for n, s, e, and w positions. Make sure and raise
+# the child site since using the 'in' option may obscure the site.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_packComponents {{when "later"}} {
+ if {$when == "later"} {
+ if {$_packToken == ""} {
+ set _packToken [after idle [itcl::code $this _packComponents now]]
+ }
+ return
+ } elseif {$when != "now"} {
+ error "bad option \"$when\": should be now or later"
+ }
+
+ set _packToken ""
+
+ #
+ # Forget about any previous placements via the grid and
+ # reset all the possible minsizes and weights for all
+ # the rows and columns.
+ #
+ foreach component {childsite filter dirs files selection} {
+ grid forget $itk_component($component)
+ }
+
+ for {set row 0} {$row < 6} {incr row} {
+ grid rowconfigure $_interior $row -minsize 0 -weight 0
+ }
+
+ for {set col 0} {$col < 4} {incr col} {
+ grid columnconfigure $_interior $col -minsize 0 -weight 0
+ }
+
+ #
+ # Place all the components based on the childsite poisition
+ # option.
+ #
+ switch $itk_option(-childsitepos) {
+ n { _nPos }
+
+ w { _wPos }
+
+ s { _sPos }
+
+ e { _ePos }
+
+ center { _centerPos }
+
+ top { _topPos }
+
+ bottom { _bottomPos }
+
+ default {
+ error "bad childsitepos option \"$itk_option(-childsitepos)\":\
+ should be n, e, s, w, center, top, or bottom"
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _nPos
+#
+# Position the childsite to the north and all the other components
+# appropriately based on the individual "on" options.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_nPos {} {
+ grid $itk_component(childsite) -row 0 -column 0 \
+ -columnspan 3 -rowspan 1 -sticky nsew
+
+ if {$itk_option(-filteron)} {
+ grid $itk_component(filter) -row 1 -column 0 \
+ -columnspan 3 -sticky ew
+ grid rowconfigure $_interior 2 -minsize 7
+ }
+
+ if {$itk_option(-dirson)} {
+ grid $itk_component(dirs) -row 3 -column 0 \
+ -columnspan 1 -sticky nsew
+ }
+ if {$itk_option(-fileson)} {
+ grid $itk_component(files) -row 3 -column 2 \
+ -columnspan 1 -sticky nsew
+ }
+ if {$itk_option(-dirson)} {
+ if {$itk_option(-fileson)} {
+ grid columnconfigure $_interior 1 -minsize 7
+ } else {
+ grid configure $itk_component(dirs) -columnspan 3 -column 0
+ }
+ } else {
+ if {$itk_option(-fileson)} {
+ grid configure $itk_component(files) -columnspan 3 -column 0
+ }
+ }
+
+ grid rowconfigure $_interior 3 -weight 1
+
+ if {$itk_option(-selectionon)} {
+ grid rowconfigure $_interior 4 -minsize 7
+ grid $itk_component(selection) -row 5 -column 0 \
+ -columnspan 3 -sticky ew
+ }
+
+ grid columnconfigure $_interior 0 -weight 1
+ grid columnconfigure $_interior 2 -weight 1
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _sPos
+#
+# Position the childsite to the south and all the other components
+# appropriately based on the individual "on" options.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_sPos {} {
+ if {$itk_option(-filteron)} {
+ grid $itk_component(filter) -row 0 -column 0 \
+ -columnspan 3 -sticky ew
+ grid rowconfigure $_interior 1 -minsize 7
+ }
+
+ if {$itk_option(-dirson)} {
+ grid $itk_component(dirs) -row 2 -column 0 \
+ -columnspan 1 -sticky nsew
+ }
+ if {$itk_option(-fileson)} {
+ grid $itk_component(files) -row 2 -column 2 \
+ -columnspan 1 -sticky nsew
+ }
+ if {$itk_option(-dirson)} {
+ if {$itk_option(-fileson)} {
+ grid columnconfigure $_interior 1 -minsize 7
+ } else {
+ grid configure $itk_component(dirs) -columnspan 3 -column 0
+ }
+ } else {
+ if {$itk_option(-fileson)} {
+ grid configure $itk_component(files) -columnspan 3 -column 0
+ }
+ }
+
+ grid rowconfigure $_interior 2 -weight 1
+
+ if {$itk_option(-selectionon)} {
+ grid rowconfigure $_interior 3 -minsize 7
+ grid $itk_component(selection) -row 4 -column 0 \
+ -columnspan 3 -sticky ew
+ }
+
+ grid $itk_component(childsite) -row 5 -column 0 \
+ -columnspan 3 -rowspan 1 -sticky nsew
+ grid columnconfigure $_interior 0 -weight 1
+ grid columnconfigure $_interior 2 -weight 1
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _ePos
+#
+# Position the childsite to the east and all the other components
+# appropriately based on the individual "on" options.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_ePos {} {
+ if {$itk_option(-filteron)} {
+ grid $itk_component(filter) -row 0 -column 0 \
+ -columnspan 3 -sticky ew
+ grid rowconfigure $_interior 1 -minsize 7
+ }
+
+ if {$itk_option(-dirson)} {
+ grid $itk_component(dirs) -row 2 -column 0 \
+ -columnspan 1 -sticky nsew
+ }
+ if {$itk_option(-fileson)} {
+ grid $itk_component(files) -row 2 -column 2 \
+ -columnspan 1 -sticky nsew
+ }
+ if {$itk_option(-dirson)} {
+ if {$itk_option(-fileson)} {
+ grid columnconfigure $_interior 1 -minsize 7
+ } else {
+ grid configure $itk_component(dirs) -columnspan 3 -column 0
+ }
+ } else {
+ if {$itk_option(-fileson)} {
+ grid configure $itk_component(files) -columnspan 3 -column 0
+ }
+ }
+
+ grid rowconfigure $_interior 2 -weight 1
+
+ if {$itk_option(-selectionon)} {
+ grid rowconfigure $_interior 3 -minsize 7
+ grid $itk_component(selection) -row 4 -column 0 \
+ -columnspan 3 -sticky ew
+ }
+
+ grid $itk_component(childsite) -row 0 -column 3 \
+ -rowspan 5 -columnspan 1 -sticky nsew
+ grid columnconfigure $_interior 0 -weight 1
+ grid columnconfigure $_interior 2 -weight 1
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _wPos
+#
+# Position the childsite to the west and all the other components
+# appropriately based on the individual "on" options.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_wPos {} {
+ grid $itk_component(childsite) -row 0 -column 0 \
+ -rowspan 5 -columnspan 1 -sticky nsew
+
+ if {$itk_option(-filteron)} {
+ grid $itk_component(filter) -row 0 -column 1 \
+ -columnspan 3 -sticky ew
+ grid rowconfigure $_interior 1 -minsize 7
+ }
+
+ if {$itk_option(-dirson)} {
+ grid $itk_component(dirs) -row 2 -column 1 \
+ -columnspan 1 -sticky nsew
+ }
+ if {$itk_option(-fileson)} {
+ grid $itk_component(files) -row 2 -column 3 \
+ -columnspan 1 -sticky nsew
+ }
+ if {$itk_option(-dirson)} {
+ if {$itk_option(-fileson)} {
+ grid columnconfigure $_interior 2 -minsize 7
+ } else {
+ grid configure $itk_component(dirs) -columnspan 3 -column 1
+ }
+ } else {
+ if {$itk_option(-fileson)} {
+ grid configure $itk_component(files) -columnspan 3 -column 1
+ }
+ }
+
+ grid rowconfigure $_interior 2 -weight 1
+
+ if {$itk_option(-selectionon)} {
+ grid rowconfigure $_interior 3 -minsize 7
+ grid $itk_component(selection) -row 4 -column 1 \
+ -columnspan 3 -sticky ew
+ }
+
+ grid columnconfigure $_interior 1 -weight 1
+ grid columnconfigure $_interior 3 -weight 1
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _topPos
+#
+# Position the childsite below the filter but above the lists and
+# all the other components appropriately based on the individual
+# "on" options.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_topPos {} {
+ if {$itk_option(-filteron)} {
+ grid $itk_component(filter) -row 0 -column 0 \
+ -columnspan 3 -sticky ew
+ }
+
+ grid $itk_component(childsite) -row 1 -column 0 \
+ -columnspan 3 -rowspan 1 -sticky nsew
+
+ if {$itk_option(-dirson)} {
+ grid $itk_component(dirs) -row 2 -column 0 -sticky nsew
+ }
+ if {$itk_option(-fileson)} {
+ grid $itk_component(files) -row 2 -column 2 -sticky nsew
+ }
+ if {$itk_option(-dirson)} {
+ if {$itk_option(-fileson)} {
+ grid columnconfigure $_interior 1 -minsize 7
+ } else {
+ grid configure $itk_component(dirs) -columnspan 3 -column 0
+ }
+ } else {
+ if {$itk_option(-fileson)} {
+ grid configure $itk_component(files) -columnspan 3 -column 0
+ }
+ }
+
+ grid rowconfigure $_interior 2 -weight 1
+
+ if {$itk_option(-selectionon)} {
+ grid rowconfigure $_interior 3 -minsize 7
+ grid $itk_component(selection) -row 4 -column 0 \
+ -columnspan 3 -sticky ew
+ }
+
+ grid columnconfigure $_interior 0 -weight 1
+ grid columnconfigure $_interior 2 -weight 1
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _centerPos
+#
+# Position the childsite between the lists and all the other
+# components appropriately based on the individual "on" options.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_centerPos {} {
+ if {$itk_option(-filteron)} {
+ grid $itk_component(filter) -row 0 -column 0 \
+ -columnspan 3 -sticky ew
+ grid rowconfigure $_interior 1 -minsize 7
+ }
+
+ if {$itk_option(-dirson)} {
+ grid $itk_component(dirs) -row 2 -column 0 \
+ -columnspan 1 -sticky nsew
+ }
+ if {$itk_option(-fileson)} {
+ grid $itk_component(files) -row 2 -column 2 \
+ -columnspan 1 -sticky nsew
+ }
+ grid $itk_component(childsite) -row 2 \
+ -columnspan 1 -rowspan 1 -sticky nsew
+
+ if {$itk_option(-dirson)} {
+ if {$itk_option(-fileson)} {
+ grid configure $itk_component(childsite) -column 1
+ grid columnconfigure $_interior 0 -weight 1
+ grid columnconfigure $_interior 2 -weight 1
+
+ } else {
+ grid configure $itk_component(dirs) -columnspan 2 -column 0
+ grid configure $itk_component(childsite) -column 2
+ grid columnconfigure $_interior 0 -weight 1
+ grid columnconfigure $_interior 1 -weight 1
+ }
+ } else {
+ grid configure $itk_component(childsite) -column 0
+ if {$itk_option(-fileson)} {
+ grid configure $itk_component(files) -columnspan 2 \
+ -column 1
+ grid columnconfigure $_interior 1 -weight 1
+ grid columnconfigure $_interior 2 -weight 1
+ } else {
+ grid columnconfigure $_interior 0 -weight 1
+ }
+ }
+
+ grid rowconfigure $_interior 2 -weight 1
+
+ if {$itk_option(-selectionon)} {
+ grid rowconfigure $_interior 3 -minsize 7
+ grid $itk_component(selection) -row 4 -column 0 \
+ -columnspan 3 -sticky ew
+ }
+}
+
+# ------------------------------------------------------------------
+# PRIVATE METHOD: _bottomPos
+#
+# Position the childsite below the lists and above the selection
+# and all the other components appropriately based on the individual
+# "on" options.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Fileselectionbox::_bottomPos {} {
+ if {$itk_option(-filteron)} {
+ grid $itk_component(filter) -row 0 -column 0 \
+ -columnspan 3 -sticky ew
+ grid rowconfigure $_interior 1 -minsize 7
+ }
+
+ if {$itk_option(-dirson)} {
+ grid $itk_component(dirs) -row 2 -column 0 -sticky nsew
+ }
+ if {$itk_option(-fileson)} {
+ grid $itk_component(files) -row 2 -column 2 -sticky nsew
+ }
+ if {$itk_option(-dirson)} {
+ if {$itk_option(-fileson)} {
+ grid columnconfigure $_interior 1 -minsize 7
+ } else {
+ grid configure $itk_component(dirs) -columnspan 3 -column 0
+ }
+ } else {
+ if {$itk_option(-fileson)} {
+ grid configure $itk_component(files) -columnspan 3 -column 0
+ }
+ }
+ grid rowconfigure $_interior 2 -weight 1
+
+ grid $itk_component(childsite) -row 3 -column 0 \
+ -columnspan 3 -rowspan 1 -sticky nsew
+
+ if {$itk_option(-selectionon)} {
+ grid $itk_component(selection) -row 4 -column 0 \
+ -columnspan 3 -sticky ew
+ }
+
+ grid columnconfigure $_interior 0 -weight 1
+ grid columnconfigure $_interior 2 -weight 1
+}