RE: Directory/file browser as TreeView
- From: "Ratcliffe, Jeffrey (Peters)" <Jeffrey Ratcliffe External eads com>
- To: "'zentara'" <zentara1 sbcglobal net>, gtk-perl-list gnome org
- Subject: RE: Directory/file browser as TreeView
- Date: Thu, 28 Sep 2006 15:49:20 +0200
When I navigated to /home/zentara, it took 12 seconds from the time I
clicked
the triangle icon, to the point where it was finished. That is
unacceptable,
because I'm tempted to think I missed the small icon, and click multiple
times.
When I use my canvas based model( on Tk) it was less than a second.
I've just downloaded your Tk version. Two minor points
- it seems to have failed an automatic CPAN make test because you didn't list the Tk dependency.
- I had to comment out the first line of the Makefile.PL to get it to make on my machine
But like I said, it's just for the sake of discussion, because maybe you
can
figure a way to limit that recursion somehow with treeview.... I couldn't.
OK. I realised that fully populating the subdirectories to show the arrow might be slow. Here is a version
that just looks far enough ahead to see whether there is a subdirectory there and puts a dummy child in the
tree, only filling it fully when required.
As you will see from the debugging messages I have put in, the tree is being properly populated. But for
reasons I don't understand, you can't expand the tree.
Any ideas?
#!/usr/bin/perl
use warnings;
use strict;
use Gtk2 -init;
use Gtk2::SimpleList;
use Glib qw(TRUE FALSE);
my $window = Gtk2::Window -> new;
$window -> signal_connect ( destroy => sub { Gtk2 -> main_quit; } );
$window -> set_default_size (800, 600);
my $hpaned = Gtk2::HPaned -> new;
$window -> add ( $hpaned );
my $scwin_dirs = Gtk2::ScrolledWindow -> new;
$scwin_dirs -> set_policy ('automatic', 'automatic');
$hpaned -> pack1 ($scwin_dirs, TRUE, TRUE);
# Directory name, full path
my $tree_store = Gtk2::TreeStore->new('Glib::String', 'Glib::String');
my $tree_view = Gtk2::TreeView->new($tree_store);
my $column = Gtk2::TreeViewColumn->new_with_attributes('', Gtk2::CellRendererText->new(), text => "0");
$tree_view->append_column($column);
$tree_view->set_headers_visible(FALSE);
$tree_view->signal_connect (button_release_event => \&cd);
$tree_view->signal_connect ('row-expanded' => \&populate_tree);
my $child = $tree_store->append(undef);
$tree_store->set($child, 0, '/', 1, '/');
$tree_store->append($child) if (has_subdir('/'));
print_tree();
$scwin_dirs -> add($tree_view);
my $scwin_files = Gtk2::ScrolledWindow -> new;
$scwin_files -> set_policy ('automatic', 'automatic');
$hpaned -> pack2 ($scwin_files, TRUE, TRUE);
my $slist = Gtk2::SimpleList -> new('Filename' => 'text');
$scwin_files -> add_with_viewport($slist);
$window -> show_all;
Gtk2 -> main;
# Add to directory treeview
sub add_to_tree {
my ($tree_store, $parent, $dir, $abs_path) = @_;
my $tree_model = $tree_view->get_model();
# If $parent already has children, then remove them first
my $child = $tree_model->iter_children ($parent);
while ($child) {
$tree_store->remove ($child);
$child = $tree_model->iter_children ($parent);
}
# Add children from directory listing
opendir(DIRHANDLE, $abs_path) || die "Cannot open directory: $!\n";
foreach my $subdir (sort readdir(DIRHANDLE)) {
if ($subdir ne '.' and $subdir ne '..'
and -d $abs_path.$subdir and -r $abs_path.$subdir) {
print "adding $subdir\n";
my $child = $tree_store->append($parent);
$tree_store->set($child, 0, $subdir, 1, "$abs_path$subdir/");
}
}
closedir(DIRHANDLE);
}
# Directory expanded. Populate directory and check for subdirectories
sub populate_tree {
# $iter has been expanded
my ($tree_view, $iter, $tree_path) = @_;
my $tree_model = $tree_view->get_model();
my ($dir, $abs_path) = $tree_model->get($iter);
print "populating $abs_path\n";
add_to_tree($tree_store, $iter, $dir, $abs_path);
# for each of $iter's children add any subdirectories
my $child = $tree_model->iter_children ($iter);
while ($child) {
my ($dir, $abs_path) = $tree_model->get($child, 0, 1);
$tree_store->append($child) if (has_subdir($abs_path));
print "$abs_path has subdir\n" if (has_subdir($abs_path));
$child = $tree_model->iter_next ($child);
}
print_tree();
return;
}
sub print_tree {
my ($parent) = @_;
my $tree_model = $tree_view->get_model();
my $child = $tree_model->iter_children ($parent);
while ($child) {
my $dir = $tree_model->get($child, 1);
if ($dir) {
print "$dir\n";
}
else {
print "subdir\n";
}
print_tree($child);
$child = $tree_model->iter_next ($child);
}
}
sub has_subdir {
my ($dir) = @_;
opendir my $dh, $dir or die "Cannot open directory: $!\n";
while ( my $file = readdir($dh) ) {
if ($file !~ /^\.{1,2}$/ and -d "$dir/$file") {
closedir $dh;
return TRUE;
}
}
closedir $dh;
return;
}
# Load $slist with all filenames in selected directory
sub cd {
my $tree_model = $tree_view->get_model();
my $selection = $tree_view->get_selection();
my $iter = $selection->get_selected();
return if (!($iter));
my $abs_path = $tree_model->get($iter, 1);
# Display list of files
chdir $abs_path;
my @data;
foreach (<*>) {
# Ignoring directories
push @data, $_ if (! -d $_);
}
@{$slist->{data}} = @data;
return;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]