RTapo.comSite Last updated 12/30/2011
Home  |  Email  |  Software  |  Websites |  Tutorials & Notes |  Development |  Downloads |  Resume

Home  >  Tk::DirTree Notes


As of $VERSION = '3.023'; Tk::DirTree exhibits two irritating behaviors when run on Win32 systems, which are:

  1. After initialization, a directory tree exists for the current drive only, while other mapped drives are ignored.
  2. The order of sorted tree entries is case sensitive.

The code in Listings 1 and 2, corrects these two issues. This original code was posted by vkonovalov, at perlmonks.org, May 30, 2002.

--- Notes & Tutorial Index ---

First, redefine methods Tk::Tree::has_subdir, Tk::Tree::DirCmd, and Tk::Tree::add_to_tree, as shown in Listing 1.


Listing 1Tk::DirTree Method Redefinitions
package Tk::DirTree;

my $current_drive = {};

sub has_subdir {1}

sub DirCmd {
    my ($w, $dir, undef) = @_;
    $dir =~ s/^(\w:)$/$1\//;
    $current_drive->{lc($dir)}++;
    my $h = DirHandle->new($dir) or return;
    my @names = grep( $_ ne '.' && $_ ne '..', $h->read );
    return @names;
}

sub add_to_tree {
    my( $w, $dir, $name, $parent ) = @_;
    unless ($parent) {
        return if $current_drive->{lc("$name/")};
    }
    my $image = $w->Getimage( $w->cget('-image') );
    my $mode = 'none';
    $mode = 'open' if $w->has_subdir( $dir );

    my @args = (-image => $image, -text => $name);
    if( $parent ) {             # Add in alphabetical order.
        foreach my $sib ($w->infoChildren( $parent )) {
            if( lc($sib) gt lc($dir) ) {
                push @args, (-before => $sib);
                last;
            }
        }
    }

    $w->add( $dir, @args );
    $w->setmode( $dir, $mode );
}
1;

Second, add the code in Listing 2, right after creating a Tk::DirTree widget instance (assume $dirtree is the widget reference).


Listing 2Tk::DirTree Instance Initialization For Win32
if ($^O eq 'MSWin32') {
  require Win32API::File;
  my $prev;
  my @drv = grep($_ ne $prev && ($prev = $_),
            sort {lc($a) cmp lc($b)}
            map{s/\\$//;lc} Win32API::File::getLogicalDrives());
  $dirtree->add_to_tree($_, $_) for @drv;
}

The Tk::DirTree widget will now have a top level entry for each mapped drive, and the order of sorted tree entries will be insensitive to case.


--- top ---

Document Created September 08, 2006

RTapo.com
Copyright ©2012
Site Last updated 12/30/2011