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 <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 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
=<gt* 1>", 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* =<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* => ] *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.