The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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. 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::DirTreeB. 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 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. The "activebackground" color, however, is always fixed as the same color as the the widget's background. Default: same color as the widget's foreground color.

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).

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.

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).

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).

Name: image
Class: Image
Switch: -image

Specify an alternate xpm (tiny icon) image to be displayed to the left of each directory).

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).

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 tree 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 <TAB> 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 know 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 also create these two bitmaps and include them in the Tk directory itself (ie. /usr/local/lib/site_perl/Tk)!

$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 $widget->open(index)

$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 =<gt> ] 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 hosting 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 = 1>", meaning just close, but don't activate or scroll the window position. See also $widget->open(index)

$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. The selection state is not changed for elements outside this range. 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.

$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 =<gt> "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 =<gt> ] 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, <https://metacpan.org/author/TURNERJW>.

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:

http://www.perlfoundation.org/artistic_license_2_0

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 <ctdean@cogit.com>. Original Tcl/Tix version by Ioi Kim Lam.

KEYWORDS

filetree dirtree filesystem

SEE ALSO

Tk::DirTree, Tk::Tree, Tk::HList.