# useage: 
#    use ChoosePrinter;
#    my $printer = ChoosePrinter->new($my_window,
#                                     <'default_printer_name'>);
#
# Description:
#
# Scans through /etc/printcap and graps a list of all printers. It displays
# them in alphabetical order. If you supplied a default printer as the 2nd
# argument it will attempt to select it from the list so the user just has
# to hit the Ok button. If you do not supply a default printer it tries 
# $PRINTER.
#

# $Id: ChoosePrinter.pm,v 1.8 1999/12/13 14:44:57 pjm Exp $


package ChoosePrinter;

use strict;
use Tk;

my $debug = 0;

sub new {
    my ($type, $window, $default_printer, $printer_type) = @_;

    unless( ref $window ){
	die "ChoosePrinter was not passed a window\n";
	return undef;
    }

    unless( defined($default_printer) || $default_printer ne ''){
	$default_printer = $ENV{'PRINTER'};
    }

    $default_printer = lc($default_printer);

    my $self = {
	default_printer => "$default_printer",
	parent_window   => $window,
	printer_type    => $printer_type,
    };
    bless($self, $type);

    if( $self->getPrinters() eq "couldn't read /etc/printcap" ){
	return undef;
    }

    $self->{button_pressed} = 0;

    $self->createWindow();

    if( $self->{button_pressed} eq 'cancel' ){
	return undef;
    }
    else {
	my $index = $self->{ScrlListbox}->curselection();
	return $self->{printers}->[$index];
    }

    die "ChoosePrinter had an internal error. Please contact bug\n";

    # it should never get here!!!
    return $self;
}

sub getPrinters {
    my ($self) = @_;
    my @array;

    open PRINTCAP, "/etc/printcap" or return "couldn't read /etc/printcap";

    while(<PRINTCAP>){
	if( m/^(\w\d*\w{1,2})/ ){
#	    push @array, uc($1);
	    push @array, $1;
	}
    }

    if( $self->{printer_type} ){
	@array = grep /$self->{printer_type}$/i, @array;
    }

    # If no printers found (/etc/printcap file format changed)
    # default to this one
    if( scalar(@array) == 0 ){
        push @array, $self->{default_printer};
    }

#    foreach my $printer (@array){
#	my $reply = `lpq -P$printer`;

#	if(length($reply) < 1){
#	    warn  "$printer, Unavailable\n";
#	    $printer = "$printer, Unavailable";
#	}
#    }

    $self->{printers} = [sort @array];
}

sub createWindow {
    my ($self) = @_;

    my $mw      = $self->{parent_window}->Toplevel();
    $self->{mw} = $mw;

    $mw->title("Choose a printer");

    $mw->Label(width => 30,
	       )->pack;

    my $slb   = $mw->ScrlListbox(-width => 20,
				 -height => 10,
				 )->pack;
    $self->{ScrlListbox} = $slb;

    $mw->Label(-width => 6)->pack(); # for spacing
    
    my $buttF = $mw->Frame();

    $buttF->Button(-text    => 'Ok',
		   -width   => 6,
		   -command => sub {
		       $self->{button_pressed} = 'ok';
		   },
		   )->pack(-side => 'left');

    $buttF->Label(-width => 5)->pack(-side => 'left'); # for spacing

    $buttF->Button(-text    => 'Cancel',
		   -width   => 6,
		   -command => sub {
		       $self->{button_pressed} = 'cancel'
		   },
		   )->pack(-side => 'right');

    $buttF->pack;


    my $dialog = $mw->Dialog(-www=> 'crap',
			     -text => 'Save File?',
			     -bitmap => 'question',
			     -title => 1, #'Save File Dialog',
			     -default_button => 'www',#'Yes',
			     -buttons => '2'#[qw/Yes No Cancel/
				       ); 

    # insert printers into ScrlListbox. Try to select default printer
    my $i = 0;
    my $saved_index;

    foreach (@{$self->{printers}}){
	$slb->insert('end', $_);

	if( /$self->{default_printer}/ && $self->{default_printer}){
	    $slb->selectionSet($i);
	    $saved_index = $i;
	}
	++$i;
    }

    $slb->yview($saved_index) if defined($saved_index);

    # make sure whole window appears on screen, not just the title.

    my $f = $self->{mw}->Frame(-width => 10, -height => 20);
    $f->pack(-side => 'top');
    $self->{mw}->idletasks();
    $self->{mw}->packPropagate(0);
    $f->packForget(); 

    # center window on screen

    my $x = int(($self->{mw}->screenwidth  - $self->{mw}->reqwidth)  / 2);
    my $y = int(($self->{mw}->screenheight - $self->{mw}->reqheight) / 2);
    
    $self->{mw}->geometry("+$x+$y");

    # grap focus and wait till the user has pressed one of the buttons

    $self->{mw}->raise();
    $self->{mw}->grab();
    $self->{mw}->waitVisibility;
    $self->{mw}->update;

    $self->{mw}->waitVariable(\$self->{button_pressed});
    $self->{mw}->grabRelease;
    $self->{mw}->withdraw;
}


######
# EOF
######
1;


# $Log: ChoosePrinter.pm,v $
# Revision 1.8  1999/12/13 14:44:57  pjm
# took out warn debug statement
#
# Revision 1.7  1999/11/29 16:52:22  pjm
# changes printer name to lower case. Entries in printcap file start with
# lower case version of printer name.
# IF no printers found, will display $PRINTER anyway - backup measure
# if printcap file changes format
#
# Revision 1.6  1999/07/29 14:26:14  pjm
# does not change printer name to uppercase now.
#
# Revision 1.5  1999/07/29 14:20:18  pjm
# you can pass in an extra argument to act as a filter for the type of printer
# you want, i.e. 'BC' for Black and white, 'BC' for barcode.
#
# Revision 1.4  1999/07/29 10:10:11  pjm
# regX now works with just one printer name in printcap (^printer1:\$)
#
# Revision 1.3  1999/07/08 12:12:03  pjm
# forgot my in front of $debug, line 24.
#
# Revision 1.2  1999/07/07 17:07:08  pjm
# added $debug variable. warns on pressing cancel button id $debug set.
#
# Revision 1.1  1999/06/18 12:58:21  pjm
# Initial revision
#
