# # Fileselectionbox # ---------------------------------------------------------------------- # Implements a file selection box that allows 2 different styles. The # default style is 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 # Anthony L. Parent tony.parent@symbios.com # # @(#) $Id: fileselectionbox.itk,v 1.3 2006/09/11 20:35:55 irby Exp $ # ---------------------------------------------------------------------- # Copyright (c) 1995 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. # ====================================================================== # # Default resources, # option add *Fileselectionbox.borderWidth 2 widgetDefault option add *Fileselectionbox.filterLabel Filter widgetDefault option add *Fileselectionbox.filterLabelPos nw widgetDefault option add *Fileselectionbox.filterOn yes widgetDefault option add *Fileselectionbox.dirsLabel Directories widgetDefault option add *Fileselectionbox.dirsLabelPos nw widgetDefault option add *Fileselectionbox.dirsOn yes widgetDefault option add *Fileselectionbox.filesLabel Files widgetDefault option add *Fileselectionbox.filesLabelPos nw widgetDefault option add *Fileselectionbox.filesOn yes widgetDefault option add *Fileselectionbox.selectionLabel Selection widgetDefault option add *Fileselectionbox.selectionLabelPos nw widgetDefault option add *Fileselectionbox.selectionOn yes widgetDefault option add *Fileselectionbox.vscrollMode static widgetDefault option add *Fileselectionbox.hscrollMode static widgetDefault option add *Fileselectionbox.scrollMargin 3 widgetDefault option add *Fileselectionbox.vertMargin 7 widgetDefault option add *Fileselectionbox.horizMargin 7 widgetDefault option add *Fileselectionbox.width 470 widgetDefault option add *Fileselectionbox.height 360 widgetDefault # # 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 # ------------------------------------------------------------------ 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 -dirsfraction dirsfraction DirsFraction 50 itk_option define -selectionon selectionOn SelectionOn true itk_option define -filteron filterOn FilterOn true itk_option define -vertmargin vertMargin Margin 7 itk_option define -horizmargin horizMargin Margin 7 itk_option define -mask mask Mask {*} itk_option define -directory directory Directory {} 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 470 itk_option define -height height Height 360 itk_option define -style style Style motif public method childsite {} public method get {} public method filter {} public method _selectDir {} public method _dblSelectDir {} public method _selectFile {} public method _selectSelection {} public method _selectFilter {} protected method _packComponents {{when later}} protected method _updateLists {{when later}} private method _setFilter {} private method _setSelection {} private method _setDirList {} private method _setFileList {} private variable _packToken "" ;# non-null => _packComponents pending private variable _updateToken "" ;# non-null => _updateLists pending private variable _pwd "." ;# present working dir private variable _justify "right" ;# justification of scrolled lists } # # Provide a lowercased access method for the Fileselectionbox class. # proc ::iwidgets::fileselectionbox {pathName args} { uplevel ::iwidgets::Fileselectionbox $pathName $args } # ------------------------------------------------------------------ # CONSTRUCTOR # ------------------------------------------------------------------ body iwidgets::Fileselectionbox::constructor {args} { component hull configure -borderwidth 0 # # Create an internal frame to contain the components. # itk_component add frame { frame $itk_interior.frame } { keep -background -cursor } pack $itk_component(frame) -fill both -expand yes pack propagate $itk_component(frame) no # # Create the child site widget. # itk_component add childsite { frame $itk_interior.fsbchildsite } { keep -background -cursor } set itk_interior $itk_component(childsite) # # Create the filter entry. # itk_component add filter { iwidgets::combobox $itk_component(frame).filter -autoclear false -unique true \ -command [code $this _selectFilter] -exportselection 0 } { keep -background -borderwidth -cursor \ -foreground -highlightcolor \ -highlightthickness -insertbackground -insertborderwidth \ -insertofftime -insertontime -insertwidth -labelfont \ -labelmargin -relief -selectbackground -selectborderwidth \ -selectforeground -textbackground -textfont rename -labeltext -filterlabel filterLabel Text rename -labelpos -filterlabelpos filterLabelPos Position rename -focuscommand -filterfocuscommand \ filterFocusCommand Command } set cmd [$itk_component(filter) cget -command] set cmd "$cmd;[code $this _selectFilter]" $itk_component(filter) configure -command "$cmd" -selectioncommand "$cmd"; # # Create the upper horizontal margin frame below the filter. # itk_component add humargin { frame $itk_component(frame).humargin } { keep -background -cursor } # # Create a paned window for the directory and file lists. # itk_component add listpane { iwidgets::panedwindow $itk_component(frame).listpane -orient vertical } { keep -background -cursor } pack $itk_component(listpane) -fill both -expand yes $itk_component(listpane) add dirs; $itk_component(listpane) add files; # # Create the directory list. # itk_component add dirs { iwidgets::Scrolledlistbox [$itk_component(listpane) childsite dirs].dirs \ -selectioncommand [code $this _selectDir] \ -selectmode single -exportselection 0 \ -visibleitems 1x1 } { keep -activebackground -activerelief -background -borderwidth \ -cursor -elementborderwidth -foreground \ -highlightcolor -highlightthickness -hscrollmode\ -jump -labelfont -labelmargin -relief -repeatdelay \ -repeatinterval -sbwidth -scrollmargin -selectbackground \ -selectborderwidth -selectforeground -textbackground \ -textfont -troughcolor -vscrollmode rename -labeltext -dirslabel dirsLabel Text rename -labelpos -dirslabelpos dirsLabelPos Position rename -dblclickcommand -dbldirscommand dblDirsCommand Command } pack configure $itk_component(dirs) -side left -fill both -expand yes # # Create the vertical margin frame between the lists. # itk_component add vmargin { frame [$itk_component(listpane) childsite files].vmargin } { keep -background -cursor } pack configure $itk_component(vmargin) -side left -fill y -expand no # # Create the files list. # itk_component add files { iwidgets::Scrolledlistbox [$itk_component(listpane) childsite files].files \ -selectioncommand [code $this _selectFile] \ -selectmode single -exportselection 0 \ -visibleitems 1x1 } { keep -activebackground -activerelief -background -borderwidth \ -cursor -elementborderwidth -foreground \ -highlightcolor -highlightthickness -hscrollmode \ -jump -labelfont -labelmargin -relief -repeatdelay \ -repeatinterval -sbwidth -scrollmargin -selectbackground \ -selectborderwidth -selectforeground -textbackground \ -textfont -troughcolor -vscrollmode rename -labeltext -fileslabel filesLabel Text rename -labelpos -fileslabelpos filesLabelPos Position rename -dblclickcommand -dblfilescommand \ dblFilesCommand Command } pack configure $itk_component(files) -side left -fill both -expand yes # # Create the lower horizontal margin frame above the selection entry. # itk_component add hlmargin { frame $itk_component(frame).hlmargin } { keep -background -cursor } # # Create the selection entry. # itk_component add selection { iwidgets::combobox $itk_component(frame).selection -autoclear false -unique true \ -command [code $this _selectSelection] -exportselection 0 } { keep -background -borderwidth -cursor \ -foreground -highlightcolor \ -highlightthickness -insertbackground -insertborderwidth \ -insertofftime -insertontime -insertwidth -labelfont \ -labelmargin -relief -selectbackground -selectborderwidth \ -selectforeground -textbackground -textfont rename -labeltext -selectionlabel selectionLabel Text rename -labelpos -selectionlabelpos selectionLabelPos Position rename -focuscommand -selectionfocuscommand \ selectionFocusCommand Command } # # Explicitly handle configs that may have been ignored earlier. # eval itk_initialize $args if {$itk_option(-dbldirscommand) == {}} { configure -dbldirscommand [code $this _dblSelectDir] } # # When idle, pack the components and update the lists. # _packComponents _updateLists } # ------------------------------------------------------------------ # DESTRUCTOR # ------------------------------------------------------------------ body iwidgets::Fileselectionbox::destructor {} { if {$_packToken != ""} {after cancel $_packToken} if {$_updateToken != ""} {after cancel $_updateToken} } # ------------------------------------------------------------------ # OPTIONS # ------------------------------------------------------------------ # ------------------------------------------------------------------ # OPTION: -style # # Specifies the style of the file selection box motif or notif # (default motif) # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::style { switch $itk_option(-style) { motif { pack forget [$itk_component(filter) component arrowBtn] pack forget [$itk_component(selection) component arrowBtn] set _justify right $itk_component(listpane) configure -thickness 0; $itk_component(listpane) configure -sashwidth 0; pack $itk_component(vmargin) -side left \ -before $itk_component(files) } notif { pack [$itk_component(filter) component arrowBtn] pack [$itk_component(selection) component arrowBtn] set _justify left $itk_component(listpane) configure -thickness 3; $itk_component(listpane) configure -sashwidth 10; pack forget $itk_component(vmargin) } default { error "bad style option \"$itk_option(-style)\":\ should be motif or notif"; } } filter; } # ------------------------------------------------------------------ # OPTION: -childsitepos # # Specifies the position of the child site in the selection box. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::childsitepos { _packComponents } # ------------------------------------------------------------------ # OPTION: -fileson # # Specifies whether or not to display the files list. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::fileson { if {$itk_option(-fileson)} { $itk_component(listpane) show files set filesfraction [expr 100 - $itk_option(-dirsfraction)]; $itk_component(listpane) fraction \ $itk_option(-dirsfraction) $filesfraction pack configure $itk_component(files) -side right -fill both -expand yes _updateLists } else { $itk_component(listpane) hide files } } # ------------------------------------------------------------------ # OPTION: -dirson # # Specifies whether or not to display the dirs list. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::dirson { if {$itk_option(-dirson)} { pack configure $itk_component(dirs) -side left -fill both -expand yes $itk_component(listpane) show dirs set filesfraction [expr 100 - $itk_option(-dirsfraction)]; $itk_component(listpane) fraction \ $itk_option(-dirsfraction) $filesfraction _updateLists } else { $itk_component(listpane) hide dirs } } # ------------------------------------------------------------------ # OPTION: -dirsfraction # # Specifies whether or not to display the dirs list. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::dirsfraction { if {$itk_option(-dirson)} { if {[winfo manager $itk_component(listpane)] != ""} { set filesfraction [expr 100 - $itk_option(-dirsfraction)]; $itk_component(listpane) fraction \ $itk_option(-dirsfraction) $filesfraction } } } # ------------------------------------------------------------------ # OPTION: -selectionon # # Specifies whether or not to display the selection entry widget. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::selectionon { if {$itk_option(-selectionon)} { pack configure $itk_component(hlmargin) -side top \ -after $itk_component(listpane) pack configure $itk_component(selection) -fill x \ -after $itk_component(hlmargin) -side top } else { pack forget $itk_component(hlmargin) pack forget $itk_component(selection) } } # ------------------------------------------------------------------ # OPTION: -filteron # # Specifies whether or not to display the filter entry widget. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::filteron { if {$itk_option(-filteron)} { pack configure $itk_component(humargin) -side top \ -before $itk_component(listpane) pack configure $itk_component(filter) -fill x \ -before $itk_component(humargin) -side top } else { pack forget $itk_component(humargin) pack forget $itk_component(filter) } } # ------------------------------------------------------------------ # OPTION: -vertmargin (depreciated) # # Specifies distance between the directory and file lists. # this option really only has meaning when the -style option is set # to 'motif' # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::vertmargin { set pixels [winfo pixels $itk_component(vmargin) $itk_option(-vertmargin)] set itk_option(-vertmargin) $pixels $itk_component(vmargin) configure -width $pixels -height $pixels } # ------------------------------------------------------------------ # OPTION: -horizmargin # # Specifies distance between the lists and filter/selection entries. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::horizmargin { set pixels [winfo pixels $itk_component(humargin) \ $itk_option(-horizmargin)] set itk_option(-horizmargin) $pixels $itk_component(humargin) configure -width $pixels -height $pixels $itk_component(hlmargin) configure -width $pixels -height $pixels } # ------------------------------------------------------------------ # OPTION: -mask # # Specifies the initial file mask string. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::mask { global tcl_platform set prefix $_pwd # # Remove automounter paths. # if {$tcl_platform(platform) == "unix"} { regsub {^/(tmp_mnt|export)} $prefix {} prefix; } set curFilter $itk_option(-mask); $itk_component(filter) delete entry 0 end $itk_component(filter) insert entry 0 [file join $_pwd $itk_option(-mask)] # # Make sure the right most text is visable. # [$itk_component(filter) component entry] xview moveto 1 } # ------------------------------------------------------------------ # OPTION: -directory # # Specifies the initial default directory. # ------------------------------------------------------------------ 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: -nomatchstring # # Specifies the string to be displayed in the files list should # not regular files exist in the directory. # ------------------------------------------------------------------ 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. # ------------------------------------------------------------------ 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. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::filesearchcommand { } # ------------------------------------------------------------------ # OPTION: -selectioncommand # # Specifies a command to be executed upon pressing return in the # selection entry widget. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::selectioncommand { } # ------------------------------------------------------------------ # OPTION: -filtercommand # # Specifies a command to be executed upon pressing return in the # filter entry widget. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::filtercommand { } # ------------------------------------------------------------------ # OPTION: -selectdircommand # # Specifies a command to be executed following selection of a # directory in the directory list. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::selectdircommand { } # ------------------------------------------------------------------ # OPTION: -selectfilecommand # # Specifies a command to be executed following selection of a # file in the files list. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::selectfilecommand { } # ------------------------------------------------------------------ # OPTION: -invalid # # Specify a command to executed should the filter contents be # proven invalid. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::invalid { } # ------------------------------------------------------------------ # OPTION: -filetype # # Specify the type of files which may appear in the file list. # ------------------------------------------------------------------ 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. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::width { set pixels \ [winfo pixels $itk_component(frame) $itk_option(-width)] $itk_component(frame) config -width $pixels } # ------------------------------------------------------------------ # OPTION: -height # # Specifies the height of the file selection box. The value may be # specified in any of the forms acceptable to Tk_GetPixels. # ------------------------------------------------------------------ configbody iwidgets::Fileselectionbox::height { set pixels [winfo pixels $itk_component(frame) $itk_option(-height)] $itk_component(frame) config -height $pixels } # ------------------------------------------------------------------ # METHODS # ------------------------------------------------------------------ # ------------------------------------------------------------------ # METHOD: childsite # # Returns the path name of the child site widget. # ------------------------------------------------------------------ body iwidgets::Fileselectionbox::childsite {} { return $itk_component(childsite) } # ------------------------------------------------------------------ # METHOD: get # # Returns the current selection. # ------------------------------------------------------------------ body iwidgets::Fileselectionbox::get {} { set curFilter [$itk_component(filter) get] if {[lsearch -exact [$itk_component(filter) cget -items] \ $curFilter] != -1} { $itk_component(filter) insert list end "$curFilter" } set selection [$itk_component(selection) get] if {[lsearch -exact [$itk_component(selection) cget -items] \ $selection] != -1} { $itk_component(selection) insert list 0 "$selection" } $itk_component(selection) delete entry 0 end $itk_component(selection) insert entry 0 $selection $itk_component(filter) delete entry 0 end $itk_component(filter) insert entry 0 $curFilter # # Make sure the right most text is visable. # [$itk_component(filter) component entry] xview moveto 1 return $selection } # ------------------------------------------------------------------ # 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. # ------------------------------------------------------------------ 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. # ------------------------------------------------------------------ body iwidgets::Fileselectionbox::_updateLists {{when "later"}} { switch -- $when { later { if {$_updateToken == ""} { set _updateToken [after idle [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 $_justify } if {$itk_option(-fileson)} { $itk_component(files) justify $_justify } 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.. # ------------------------------------------------------------------ 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"} { regsub {^/(tmp_mnt|export)} $prefix {} prefix } $itk_component(filter) delete entry 0 end $itk_component(filter) insert entry 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) component entry] 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. # ------------------------------------------------------------------ body iwidgets::Fileselectionbox::_setSelection {} { global tcl_platform $itk_component(selection) delete entry 0 end if {$itk_option(-fileson)} { set selection [$itk_component(files) getcurselection] if {[file pathtype $selection] != "absolute"} { set selection [file join $_pwd $selection] } # # Remove automounter paths. # if {$tcl_platform(platform) == "unix"} { regsub {^/(tmp_mnt|export)} $selection {} selection; } if {$selection != $itk_option(-nomatchstring)} { $itk_component(selection) insert entry 0 $selection } } 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 ..] } } # # Remove automounter paths. # if {$tcl_platform(platform) == "unix"} { regsub {^/(tmp_mnt|export)} $selection {} selection; } $itk_component(selection) insert entry 0 $selection } $itk_component(selection) icursor end # # Make sure the right most text is visable. # [$itk_component(selection) component entry] 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. # ------------------------------------------------------------------ body iwidgets::Fileselectionbox::_setDirList {} { $itk_component(dirs) clear if {$itk_option(-dirsearchcommand) == {}} { set cwd $_pwd foreach i [lsort [glob -nocomplain [file join $cwd .*] [file join $cwd *]]] { if {[file isdirectory $i]} { switch $itk_option(-style) { motif { set insert "$i"} notif { set insert "[file tail $i]";} default { set insert "$i"; error "bad style option \"$itk_option(-style)\":\ should be motif or notif"; } } $itk_component(dirs) insert end "$insert" } } } 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. # ------------------------------------------------------------------ body iwidgets::Fileselectionbox::_setFileList {} { $itk_component(files) clear set mask [file tail [$itk_component(filter) get]] if {$itk_option(-filesearchcommand) == {}} { foreach i [lsort [glob -nocomplain [file join $_pwd $mask]]] { if {($itk_option(-filetype) == "regular" && \ ! [file isdirectory $i]) || \ ($itk_option(-filetype) == "directory" && \ [file isdirectory $i]) || \ ($itk_option(-filetype) == "any")} { switch $itk_option(-style) { motif { set insert "$i"} notif { set insert "[file tail $i]"} default { set insert "$i"; error "bad style option \"$itk_option(-style)\":\ should be motif or notif"; } } $itk_component(files) insert end "$insert" } } } else { foreach file [uplevel #0 $itk_option(-filesearchcommand) $_pwd $mask] { $itk_component(files) insert end $file } } if {[$itk_component(files) size] == 0} { $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. # ------------------------------------------------------------------ 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. # ------------------------------------------------------------------ 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. # ------------------------------------------------------------------ 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. # ------------------------------------------------------------------ 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. # ------------------------------------------------------------------ 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. # ------------------------------------------------------------------ body iwidgets::Fileselectionbox::_packComponents {{when "later"}} { if {$when == "later"} { if {$_packToken == ""} { set _packToken [after idle [code $this _packComponents now]] } return } elseif {$when != "now"} { error "bad option \"$when\": should be now or later" } set _packToken "" switch $itk_option(-childsitepos) { n { pack configure $itk_component(childsite) -side top \ -in $itk_component(hull) pack configure $itk_component(frame) -side top \ -after $itk_component(childsite) } w { pack configure $itk_component(frame) -side right pack configure $itk_component(childsite) -side left \ -after $itk_component(frame) \ -in $itk_component(hull) } s { pack configure $itk_component(frame) -side top pack configure $itk_component(childsite) -side top \ -after $itk_component(frame) \ -in $itk_component(hull) } e { pack configure $itk_component(frame) -side left pack configure $itk_component(childsite) -side right \ -before $itk_component(frame) \ -in $itk_component(hull) } default { error "bad childsitepos option \"$itk_option(-childsitepos)\":\ should be n, e, s, or w" } } raise $itk_component(childsite) }