NAME Tk::FileTree - Tk::DirTree like widget for displaying & manipulating directories (and files). SYNOPSIS #!/usr/bin/perl use Tk; use Tk::FileTree; my $bummer = ($^O =~ /MSWin/); my $top = MainWindow->new; my $tree = $top->Scrolled('FileTree', -scrollbars => 'osoe', -selectmode => 'extended', -width => 40, -height => 16, -takefocus => 1, )->pack( -fill => 'both', -expand => 1); my $ok = $top->Button( qw/-text Show -underline 0/, -command => \&showme ); my $cancel = $top->Button( qw/-text Quit -underline 0/, -command => sub { exit } ); $ok->pack( qw/-side left -padx 10 -pady 10/ ); $cancel->pack( qw/-side right -padx 10 -pady 10/ ); my ($root, $home); if ($bummer) { $home = $ENV{'HOMEDRIVE'} . $ENV{'HOMEPATH'}; $home ||= $ENV{'USERPROFILE'}; ($root = $home) =~ s#\\[^\\]*$##; } else { $root = '/home'; $home = "/home/$ENV{'USER'}"; $home = $root = '/' unless (-d $home); } print "--home=$home= root=$root=\n"; $tree->set_dir($home, -root => $root); MainLoop; sub showme { my @selection = $tree->selectionGet; print "--Show me: active=".$tree->index('active')."=\n"; print "--selected=".join('|',@selection)."=\n"; foreach my $i (@selection) { print "-----$i selected.\n"; } my $state = $tree->state(); print "--state=$state=\n"; print (($state =~ /d/) ? "--enabling.\n" : "--disabling.\n"); $tree->state(($state =~ /d/) ? 'normal' : 'disabled'); } DESCRIPTION Creates a widget to display a file-system (or part of it) in a tree format. Works very similar to Tk::DirTree, but displays both files and subdirectories by default. Each subdirectory includes an indicator icon resembling [+] or [-] to either expand and view it's contents (files and subdiretories) or collapse them respectively. A separate icon is displayed for files and subdirectories making it easier to tell them apart. Options allow users to select a file, a directory, or multiple entries (like a listbox) which can be returned to the program for further processing. This widget is derived from Tk::DirTree. It provides additional features, including listing files, in addition to the subdirectories, options (filters) to limit which files are displayed (by specificy including or excluding a list of file extensions), and additional bindings and functions to enable user-selection and interaction with specific files and directories from within other programs. I took Tk::DirTree, renamed it and modified it to create this module primarily to be able to add a "tree-view" option to my Perl-Tk based filemanager called JFM5, which allows users to select and perform common functions on files and directories on their system, and others (via Net::xFTP). I have previously created other modules toward this effort, namely Tk::HMListbox and Tk::JThumbnail. These modules provide the different "views": Detailed list, Image list, and now Tree-view, respectively. STANDARD OPTIONS -background -borderwidth -cursor -disabledforeground -exportselection -font -foreground -height -highlightbackground -highlightcolor -highlightthickness -relief -scrollbars -selectbackground -selectborderwidth -selectforeground -state -takefocus -width -xscrollcommand -yscrollcommand See Tk::options for details of the standard options. WIDGET-SPECIFIC OPTIONS Name: activeForeground Class: activeForeground Switch: -activeforeground Specifies an alternate color for the foreground of the "active" entry (the one the text cursor is on). This entry is also shown with a hashed box around it. NOTE: The "activebackground" color, however, is always fixed to the same color as the widget's background, due to the fact that the underlying Tk::HList module only sets the text and icon areas to the active background, rather than the entire row resulting in a somewhat ugly appearance if the row is "active" but not "selected". DEFAULT: Same color as the widget's foreground color. Name: browseCmd Class: BrowseCmd Switch: -browsecmd Specifies a callback to call whenever the user browses on a file or directory (usually by single-clicking on the name). The callback is called with one argument: the complete pathname of the file / directory. Name: command Class: Command Switch: -command Specifies the callback to be called when the user activates on a file or directory (usually by double-clicking on the name). The callback is called with one argument, the complete pathname of the file / directory. Name: dirCmd Class: DirCmd Switch: -dircmd Callback function to obtain the list of directories and files for display. A sensible default is provided and it should not be overridden unless you know what you are doing! It takes three arguments: a widget object handle, a directory path, and a boolean value (TRUE for include hidden (dot) files or FALSE to exclude them). Tk::DirTree documentation: Specifies the callback to be called when a directory listing is needed for a particular directory. If this option is not specified, by default the DirTree widget will attempt to read the directory as a Unix directory. On special occasions, the application programmer may want to supply a special method for reading directories: for example, when he needs to list remote directories. In this case, the -dircmd option can be used. The specified callback accepts two arguments: the first is the name of the directory to be listed; the second is a Boolean value indicating whether hidden sub-directories should be listed. This callback returns a list of names of the sub-directories of this directory. Name: dirTree Class: DirTree Switch: -dirtree Boolean option to only show directories (like Tk::DirTree) if TRUE, show both directories and files if FALSE. Use this to work as a drop-in replacement for Tk::DirTree. To truly emulate Tk::DirTree's behavior, one should probably also specify "-takefocus => 1", as that seems to be it's default focus model. DEFAULT: *FALSE* (Show both directories and files). Name: exclude Class: Exclude Switch: -exclude Specify a reference to an array of file-extensions to be excluded. Note: Not applicable to directory names (case insensitive). See also: -include. DEFAULT: *[]* (Do not exclude any files). EXAMPLE: -exclude => ['exe', 'obj'] (Exclude M$-Windows object and executable files). Switch: -height Specifies the desired height for the window. I'm not sure what units it uses, so users will need to use trial and error and seems to work differently than the -width option. See also: -width. Name: fileimage Class: Image Switch: -fileimage Specify an alternate xpm (tiny icon) image to be displayed to the left of each file displayed which is not a directory). See also: -image. DEFAULT: A sensible default icon of a white sheet of paper with a dogeared corner is provided. Name: image Class: Image Switch: -image Specify an alternate xpm (tiny icon) image to be displayed to the left of each directory). See also: -fileimage. DEFAULT: A sensible default icon of a yellow folder is provided (the same one used by Tk::DirTree). Name: include Class: Include Switch: -include Specify a reference to an array of file-extensions to be included, all other entensions will be excluded. Note: Not applied to directory names (case insensitive). See also: -exclude. DEFAULT: *[]* (Include all files). EXAMPLE: -include => ['pl', 'pm'] (Include only Perl files). Name: root Class: Directory Switch: -root Specify a "root path" above which the user will not be able to expand to view any other subdirectories or files (by clicking the little [-] icon next to each directory). DEFAULT: *"/"* (Allow user to expand any level). Name: selectMode Class: SelectMode Switch: -selectmode Specifies one of several styles for manipulating the selection. The value of the option may be arbitrary, but the default bindings expect it to be either single, browse, multiple, extended or dragdrop. DEFAULT: *browse*. Name: -showcursoralways Class: -showcursoralways Switch: -showcursoralways This option, when set to 1 always shows the active cursor. When set to 0, the active cursor is only shown when the widget has the keyboard focus. NOTE: The option: *-takefocus => 1* will cause the mouse to give keyboard focus to the widget when clicked on an item, which while activating the item clicked on will also make the active cursor visible. DEFAULT: *0* (Hide cursor when focus leaves the widget). Name: showHidden Class: ShowHidden Switch: -showhidden Boolean option to include hidden (dot) files and directories (if TRUE), otherwise, exclude them. DEFAULT: *FALSE* (Exclude hidden directories and files (those that begin with a dot (".")). Switch: -state Specifies one of two states for the widget: normal or disabled. If the widget is disabled then items may not be selected, items are drawn in the -disabledforeground color, and selection cannot be modified and is not shown (though selection information is retained). Note: The active and any selected items are saved when disabling the widget, and restored when re-enabled. Name: takeFocus Class: TakeFocus Switch: -takefocus There are actually three different focusing options: Specify 1 to both allow the widget to take keyboard focus itself and to enable grabbing the keyboard focus when a user clicks on a row in the tree. Specify '' to allow the widget to take focus (via the circulate order) but do not grab the focus when a user clicks on (selects) a row. This is the default focusing model. Specify 0 to not allow the widget to receive the keyboard focus. Disabling the widget will also prevent focus while disabled, but restore the previous focusing policy when re-enabled. DEFAULT: *""* (Empty string, also a "false" value, the default Tk focusing option), but different from *0* (zero), as explained above. Name: width Class: Width Switch: -width Seems to specify the desired width for the widget in tenths of inches, though I haven't confirmed if this is absolute. It also seems to work differently than the -height option. See also -height. WIDGET METHODS The FileTree method creates a widget object. The widget object can also be created via Scrolled('FileTree'). This object supports the configure and cget methods described in Tk::options which can be used to enquire and modify the options described above. The widget also inherits the methods provided by the generic Tk::Widget, Tk::HList and Tk::Tree classes. To create a FileTree widget: *$widget* = *$parent*->FileTree(?*options*?); The following additional methods are available for FileTree widgets: *$widget*->activate(*index*) Sets the active element and the selection anchor to the one indicated by *index*. If *index* is outside the range of elements in the tree no element is activated. The active element is drawn with a thin hashed border, and its index may be retrieved with the index active or anchor. Note: The "*index*" for FileTree widgets (if not *active* or anchor, must be a full path-name to a file or directory in the tree. Also note, if the activated entry is not visible (inside a collapsed directory), the directories above it will be expanded (as if the user clicked the [+] icon) to make it visible (as the parent *Tk::Tree* widget requires this in order to be able to activate an entry. *$widget*->add_pathimage(*path*, *ExpandedImage [+]*, *CollapsedImage [-]*) Overrides the default "[+]" and "[-]" icon images (black foreground) used for each directory in the tree. Normally, this is unnecessary, but one specific use (useful for users) is adding a matching set with a white foreground if setting the palette or background color to a "dark" color (where the foreground text is all set to white because a black text foreground is difficult to see). NOTE: Any program allowing users to change the color palette to be changed will also need to unpack, destroy, recreate, add the additional pair of images (with white foregrounds) and repack the FileTree widget if it determines that the foreground color is being changed from black to white (ie. palette has changed from a "light" to a "dark" background). The reason for this extra work is due to the fact that there is no known way to go through and reset and redraw all the icons displayed when the palette is changed. Tk does not include white-foreground bitmaps of these two images, so the author of such a program will need to either also create these two bitmaps and include them in the Tk directory itself (ie. /usr/local/lib/site_perl/Tk); or simply use the two corresponding "*_night.xpm" icon images included with this module! *$widget*->chdir(*full_directory_path* [, *ops* ]) Synonym for *$widget*->set_dir(*full_directory_path* [, *ops* ]) - a holdover from Tk::DirTree. See setdir below. *$widget*->close(*index*) Collapses the display of the directory specified by *index*, if it is a directory and it is currently expanded (files and subdirectories are currently displayed. If successful, it also activates and scrolls the entry into view. See also the open method. *$widget*->curselection Convenience method that returns a list containing the "indices" (values) of all of the elements in the HListbox that are currently selected. If there are no elements selected in the tree then an empty list is returned. The values returned are always fully-qualified file and directory names. It is equivalent to *$widget*->selectionGet. *$widget*->delete(*index*) Deletes one or all elements of the HListbox. The "*index*" must eiter be must be a full path-name to a file or directory in the tree or "*all*", meaning delete the entire tree. *$widget*->hide([*-entry* => ] *index*) Given an *index*, sets the entry to "hidden" so that it does not display in the tree (but maintains it's index. The "*-entry*" argument is unnecessary, but retained for Tk::HList compatability. See also the show method. *$widget*->index(*index*) Returns the "normalized" version of the entry that corresponds to *index*. "normalized" means that file and directory paths are converted into a valid "*nix" format ("/" instead of "\"), any trailing "/" is removed unless the path is "/" (root). This can still be passed to any of the public methods, which will ensure they're in the proper format for the host operating system. Two special values may also be given for *index*: *active* and *anchor*, which are similar for *Tk::HList*-based widgets and return the current active element's index. The subtle difference is that "*anchor*" is not valid when the widget is disabled, but "*active*" will still return the saved anchor position. *$widget*->open(*index* [, *ops* ]) Expands the display of the directory specified by *index*, if it is a directory and it is currently collapsed (files and subdirectories are currently not displayed. If successful, it also activates and scrolls the entry into view. The optional *ops* represents a hash of additional options. Currently, the only valid value is "*-silent =", meaning just open, but don't activate or scroll the window position. See also the close method. *$widget*->see(*index*) Adjust the view in the tree so that the element given by *index* is visible. If the element is already visible then the command has no effect; if the element is near one edge of the window then the widget scrolls to bring the element into view at the edge. If *index* is hidden or not a valid entry, this function is ignored. *$widget*->selectionClear([*index*]) If *index* is specified and it's element is currently selected, it will be unselected. If no *index* is specified, all selected items will be unselected, clearing the selection list. *$widget*->selectionIncludes(*index*) Returns 1 if the element indicated by *index* is currently selected, 0 if it isn't. *$widget*->selectionSet(*index*) Adds entry specified by *index* to the selected list if it is not already selected. Note: Unlike listboxes, etc. only a single element may be selected per call. Ranges are not accepted (ignored). *$widget*->selectionToggle(*index*) If the entry specified by *index* is currently selected, it will be unselected, otherwise, it will be selected. *$widget*->set_dir(*full_directory_path* [, *ops* ]) Sets the directory path to be opened and displayed in the widget. The entire file-system (drive-letter in M$-Windows) will be accessible, but initially collapsed. It can add any new files and subdirectories it finds in the tree if it has changed since the previous call. To limit how far up the file-system that users can can expand, specify *-root* = "*directory_path*", for example: $widget->set_dir("/home/user/documents", -root => "/home/user"). This would open the user "user"'s "documents" directory expanded, but not permit him to expand either root ("/" or "/home" to see their contents. *$widget*->show([*-entry* => ] *index*) Given an *index*, sets the hidden entry to visible so that it is displayed in the tree (but maintains it's index. The "*-entry*" argument is unnecessary, but retained for Tk::HList compatability. See also the hide method. AUTHOR Jim Turner, "". LICENSE AND COPYRIGHT Copyright (c) 2022 Jim Turner. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at: Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed. Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ACKNOWLEDGEMENTS Tk::FileTree is a derived work from Tk::DirTree: Perl/TK version by Chris Dean . Original Tcl/Tix version by Ioi Kim Lam. KEYWORDS filetree dirtree filesystem SEE ALSO Tk::DirTree, Tk::Tree, Tk::HList.