/usr/local/CPAN/xisofs/selector.pm
# xisofs v1.3 Perl/Tk Interface to mkisofs / cdwrite
# Copyright (c) 1997 Steve Sherwood (pariah@netcomuk.co.uk)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
package selector;
use wcenter;
use Tk::BrowseEntry;
#---------------------------------
# Reset the file types filter list
#---------------------------------
sub add_type
{
my ($ext,$desc) = @_;
push(@selector::types,"$ext!!!$desc");
}
sub reset_types
{
undef @selector::types;
}
#------------------------
# Display the file dialog
#------------------------
sub file
{
my ($parent,$title,$name,$rt) = @_;
$parent->Busy;
if (length($rt) == 0)
{
if (length($selector::root) == 0)
{
chomp ($selector::root = `pwd`);
}
}
else
{
$selector::root = $rt;
}
if ($#selector::types == -1)
{
add_type('*','All File Types');
}
my $popup = $parent->Toplevel;
$popup->title($title);
$popup->configure(-background => 'grey80');
wcenter::offset($popup,140,235);
$selector::top = $popup;
#---------------------
# where frame
#---------------------
my $whereFrame = $popup->Frame->pack(
-pady => 5,
-side => 'top');
$whereFrame->Label(
-text => 'Current Location')->pack(
-padx => 5,
-side => 'left');
$whereFrame->Button(
-command => sub{upbutton()},
-text => 'Up',
-activebackground => 'grey80',
-borderwidth => 1)->pack(
-padx => 5,
-side => 'right');
$selector::whereEntry = $whereFrame->Entry(
-background => 'AntiqueWhite',
-relief => 'sunken',
-borderwidth => 2,
-width => 50,
-font => '8x13',
-highlightthickness => 0)->pack(
-side => 'right',
-padx => 5);
$selector::whereEntry->insert('end',$selector::root);
$selector::whereEntry->bindtags('all');
#---------------------
# Top & bottom frames
#---------------------
my $topFrame = $popup->Frame->pack(
-side => 'top',
-fill => 'both',
-expand => 'yes');
my $bottomFrame = $popup->Frame->pack(
-side => 'bottom',
-fill => 'x');
#-------------------
# The directory list
#-------------------
my $dirFrame = $topFrame->Frame->pack(
-padx => 5,
-side => 'left',
-expand => 'yes',
-fill => 'both');
$dirFrame->Label(
-text => 'Directories',
-foreground => 'red4')->pack(
-pady => 5,
-side => 'top');
my $dirListFrame = $dirFrame->Frame->pack(
-side => 'top',
-expand => 'yes',
-fill => 'both');
my $dirListScrollbar = $dirListFrame->Scrollbar->pack(
-side => 'right',
-fill => 'y');
$selector::dirListBox = $dirListFrame->Listbox(
-width => 30,
-font => '8x13',
-background => 'PapayaWhip',
-yscrollcommand => [$dirListScrollbar => 'set'])->pack(
-side => 'left',
-expand => 'yes',
-fill => 'both');
$dirListScrollbar->configure(-command => [$dirListBox => 'yview']);
$selector::dirListBox->bind('<Double-1>' =>
sub {
double_dir();
});
#--------------
# The file list
#--------------
my $fileFrame = $topFrame->Frame->pack(
-side => 'right',
-padx => 5,
-expand => 'yes',
-fill => 'both');
$fileFrame->Label(
-text => 'Files',
-foreground => 'red4')->pack(
-pady => 5,
-side => 'top');
my $fileListFrame = $fileFrame->Frame->pack(
-side => 'top',
-expand => 'yes',
-fill => 'both');
my $fileListScrollbar = $fileListFrame->Scrollbar->pack(
-side => 'right',
-fill => 'y');
$selector::fileListBox = $fileListFrame->Listbox(
-width => 30,
-font => '8x13',
-background => 'PapayaWhip',
-yscrollcommand => [$fileListScrollbar => 'set'])->pack(
-side => 'left',
-expand => 'yes',
-fill => 'both');
$fileListScrollbar->configure(-command => [$fileListBox => 'yview']);
$selector::fileListBox->bind('<Double-1>' =>
sub {
double_file();
});
$selector::fileListBox->bind('<1>' =>
sub {
single_file();
});
#--------------------
# The Command Buttons
#--------------------
my $buttonFrame = $bottomFrame->Frame->pack(
-side => 'right',
-pady => 5);
$selector::actionButton = $buttonFrame->Button(
-state => 'disabled',
-command => sub{action_button()},
-text => $name,
-activebackground => 'grey80',
-borderwidth => 1)->pack(
-padx => 5,
-pady => 2,
-side => 'top',
-anchor => 'w');
$buttonFrame->Button(
-command => sub{$selector::final = ''},
-activebackground => 'grey80',
-text => 'Cancel',
-borderwidth => 1)->pack(
-padx => 5,
-pady => 2,
-side => 'top',
-anchor => 'w');
#------------------
# Other information
#------------------
my $infoFrame = $bottomFrame->Frame->pack(
-side => 'left',
-fill => 'both',
-pady => 5);
#-----------------
# The Filename Box
#-----------------
my $filenameFrame = $infoFrame->Frame->pack(
-side => 'top',
-fill => 'x',
-pady => 5);
$filenameFrame->Label(
-text => 'File Name')->pack(
-padx => 5,
-side => 'left');
$selector::filenameEntry = $filenameFrame->Entry(
-font => '8x13',
-background => 'PapayaWhip',
-relief => 'sunken',
-borderwidth => 2,
-width => 50,
-highlightthickness => 0)->pack(
-side => 'right',
-padx => 5);
$selector::filenameEntry->bind('<KeyPress>' =>
sub {
my $current = get $selector::filenameEntry;
if (length($current) == 0)
{
$selector::actionButton->configure(-state => 'disabled');
}
else
{
$selector::actionButton->configure(-state => 'normal');
}
});
$selector::filenameEntry->bind('<Key-Return>' =>
sub {
action_button();
});
#-----------------
# The file type box
#-----------------
my $filetypeFrame = $infoFrame->Frame->pack(
-side => 'top',
-fill => 'x',
-pady => 5);
$filetypeFrame->Label(
-text => 'File Type')->pack(
-padx => 5,
-side => 'left');
my $filetypeSelect = $filetypeFrame->BrowseEntry(
-variable => \$browse_var,
-width => 53)->pack(
-side => 'right');
my $c = 0;
foreach(@selector::types)
{
my ($ext, $desc) = split('!!!');
$filetypeSelect->insert('end',"$desc (.$ext)");
$browse_var = "$desc (.$ext)" if ($c == 0);
$c++;
}
my $bpm = $filetypeFrame->Pixmap(
-file => "$main::ROOT/misc_icons/down.xpm");
$filetypeSelect->Subwidget("arrow")->configure(
-image => $bpm);
$filetypeSelect->Subwidget("entry")->Subwidget("entry")->configure(
-background => 'PapayaWhip');
$filetypeSelect->Subwidget("slistbox")->configure(
-background => 'PapayaWhip');
$filetypeSelect->Subwidget("slistbox")->bind('<1>' =>
sub {
set_filter($filetypeSelect);
});
my $cmd = $filetypeSelect->Subwidget("slistbox")->
Subwidget("listbox")->bind('<ButtonRelease-1>');
$filetypeSelect->Subwidget("slistbox")->
Subwidget("listbox")->bind('<ButtonRelease-1>' =>
sub {
&$cmd;
set_filter($filetypeSelect);
});
display_filter();
my $old_focus = $popup->focusSave;
my $old_grab = $popup->grabSave;
$popup->grab;
$popup->focus;
$popup->bind('<FocusOut>' => sub {
$popup->focus;
});
#-------------------------------
# Load in the initial file lists
#-------------------------------
load_lists();
$selector::final = '';
$parent->Unbusy;
$popup->waitVariable(\$selector::final);
$popup->grabRelease;
&$old_focus;
&$old_grab;
destroy $popup;
return $selector::final;
}
#---------------------------
# Load the files and dirs in
#---------------------------
sub load_lists
{
opendir(LS,$selector::root) || die "$dir : $!";
chomp(my @dirlist = readdir(LS));
closedir(LS);
$selector::dirListBox->delete(0,$#dirs);
$selector::fileListBox->delete(0,$#files);
undef @selector::dirs;
undef @selector::files;
if ($selector::root ne '/')
{
push(@dirs, '<..>');
$selector::dirListBox->insert('end', '<..>');
}
foreach $filename (@dirlist)
{
$_ = $filename;
next if (($_ eq ".") || ($_ eq ".."));
my ($dev, $ino, $mode, $nlink, $uid)
= lstat("$selector::root/$filename");
if (($mode & 0170000) == 0040000)
{
push(@dirs, $filename);
$selector::dirListBox->insert('end', $filename);
}
else
{
my $len = length($selector::currentFilter)+1;
my $end = substr($filename, -$len,$len);
next unless (($end eq ".$selector::currentFilter") ||
($selector::currentFilter eq '*'));
push(@files, $filename);
$selector::fileListBox->insert('end', $filename);
}
}
}
#------------------------------------------------
# Function to handle double clicks on the dir box
#------------------------------------------------
sub double_dir
{
my $new_dir = $selector::root;
my $index = $selector::dirListBox->curselection;
if ($selector::dirs[$index] ne '<..>')
{
if ($selector::root ne '/')
{
$new_dir = "$new_dir/$selector::dirs[$index]";
}
else
{
$new_dir = "/$selector::dirs[$index]";
}
}
else
{
my @tmp = split('/', $new_dir);
$#tmp--;
$new_dir = join('/',@tmp);
$new_dir = '/' if (length($new_dir) == 0);
}
if (opendir(LS,$new_dir))
{
closedir(LS);
$selector::root = $new_dir;
$selector::whereEntry->delete('0.0','end');
$selector::whereEntry->insert('end',$selector::root);
load_lists();
$selector::filenameEntry->delete('0.0','end');
$selector::actionButton->configure(-state => 'disabled');
}
}
#------------------------------------------------
# Function to handle single clicks on the file box
#------------------------------------------------
sub single_file
{
my $index = $selector::fileListBox->curselection;
$selector::filenameEntry->delete('0.0','end');
$selector::filenameEntry->insert('0.0',$selector::files[$index]);
$selector::actionButton->configure(-state => 'normal');
}
#------------------------------------------------
# Function to handle double clicks on the file box
#------------------------------------------------
sub double_file
{
my $index = $selector::fileListBox->curselection;
if ($selector::root eq '/')
{
$selector::final = "/$selector::files[$index]";
}
else
{
$selector::final = "$selector::root/$selector::files[$index]";
}
}
#---------------------------------
# Function to handle the up-button
#---------------------------------
sub upbutton
{
my @tmp = split('/', $selector::root);
$#tmp--;
$selector::root = join('/',@tmp);
$selector::root = '/' if (length($selector::root) == 0);
$selector::whereEntry->delete('0.0','end');
$selector::whereEntry->insert('end',$selector::root);
load_lists();
$selector::filenameEntry->delete('0.0','end');
$selector::actionButton->configure(-state => 'disabled');
}
#--------------------------------
# Function to set the filter type
#--------------------------------
sub set_filter
{
my ($widget) = @_;
$cur = $widget->Subwidget("slistbox")->curselection;
my ($ext, $desc) = split('!!!',$selector::types[$cur]);
$selector::currentFilter = $ext;
load_lists();
$selector::filenameEntry->delete('0.0','end');
$selector::actionButton->configure(-state => 'disabled');
}
sub display_filter
{
my ($ext, $desc);
if (length($selector::currentFilter) == 0)
{
($ext,$desc) = split('!!!', $selector::types[0]);
}
else
{
foreach(@selector::types)
{
($ext, $desc) = split('!!!');
last if ($ext eq $selector::currentFilter);
}
}
$selector::currentFilter = $ext;
}
#---------------------------------------------------
# Function to handle the action button being pressed
#---------------------------------------------------
sub action_button
{
my $filename = get $selector::filenameEntry;
return if (length($filename) == 0);
my $len = length($selector::currentFilter)+1;
my $end = substr($filename, -$len,$len);
if (($end ne ".$selector::currentFilter")&&
($selector::currentFilter ne '*'))
{
$filename = "$filename.$selector::currentFilter";
}
if ($selector::root eq '/')
{
$selector::final = "/$filename";
}
else
{
$selector::final = "$selector::root/$filename";
}
}
1;