diff options
Diffstat (limited to 'perl-install/install/share/po/id.po')
0 files changed, 0 insertions, 0 deletions
index : drakx | ||
Mageia Installer and base platform for many utilities | Thierry Vignaud [tv] |
summaryrefslogtreecommitdiffstats |
package printer::printerdrake;
# $Id$
use strict;
use common;
use modules;
use network::network;
use log;
use interactive;
use printer::main;
use printer::services;
use printer::detect;
use printer::default;
use printer::data;
# Overtake translation for "(recommended)" from printer/main.pm
my $recstr = $printer::main::recstr;
my $precstr = $printer::main::precstr;
my $sprecstr = $printer::main::sprecstr;
my $shortdistroname = "Mandrakelinux";
my $hp1000fwtext = N("The HP LaserJet 1000 needs its firmware to be uploaded after being turned on. Download the Windows driver package from the HP web site (the firmware on the printer's CD does not work) and extract the firmware file from it by decompressing the self-extracting '.exe' file with the 'unzip' utility and searching for the 'sihp1000.img' file. Copy this file into the '/etc/printer' directory. There it will be found by the automatic uploader script and uploaded whenever the printer is connected and turned on.
");
1;
sub config_cups {
my ($printer, $security, $in, $upNetwork) = @_;
local $::isWizard = 0;
local $::isEmbedded = 0;
# Check whether the network functionality is configured and
# running
if (!check_network($printer, $in, $upNetwork, 0)) { return 0 };
#$in->set_help('configureRemoteCUPSServer') if $::isInstall;
#- hack to handle cups remote server printing,
#- first read /etc/cups/cupsd.conf for variable BrowsePoll address:port
# Return value: 0 when nothing was changed ("Apply" never pressed), 1
# when "Apply" was at least pressed once.
my $retvalue = 0;
# Read CUPS config file
@{$printer->{cupsconfig}{cupsd_conf}} =
printer::main::read_cupsd_conf();
printer::main::read_cups_config($printer);
# Read client.conf file
my ($daemonless_cups, $remote_cups_server) =
printer::main::read_client_conf();
# Read state of japanese text printing mode
my $jap_textmode = printer::main::get_jap_textmode();
# Read state for auto-correction of cupsd.conf
$printer->{cupsconfig}{autocorrection} =
printer::main::get_cups_autoconf();
my $oldautocorr = $printer->{cupsconfig}{autocorrection};
# Human-readable strings for hosts onto which the local printers
# are shared
my $maindone;
while (!$maindone) {
my $sharehosts = printer::main::makesharehostlist($printer);
my $browsepoll = printer::main::makebrowsepolllist($printer);
my $buttonclicked;
#- Show dialog
if ($in->ask_from_(
{
title => N("CUPS printer configuration"),
messages => N("Here you can choose whether the printers connected to this machine should be accessible by remote machines and by which remote machines.") .
N("You can also decide here whether printers on remote machines should be automatically made available on this machine."),
},
[
{ text => N("The printers on this machine are available to other computers"), type => 'bool',
val => \$printer->{cupsconfig}{localprintersshared},
disabled => sub {
$daemonless_cups;
} },
{ text => N("Automatically find available printers on remote machines"), type => 'bool',
val => \$printer->{cupsconfig}{remotebroadcastsaccepted},
disabled => sub {
$daemonless_cups;
} },
{ val => N("Printer sharing on hosts/networks: ") .
($printer->{cupsconfig}{customsharingsetup} ?
N("Custom configuration") :
($#{$sharehosts->{list}} >= 0 ?
($#{$sharehosts->{list}} > 1 ?
join(", ", @{$sharehosts->{list}}[0,1]) . " ..." :
join(", ", @{$sharehosts->{list}})) :
N("No remote machines"))),
type => 'button',
clicked_may_quit => sub {
$buttonclicked = "sharehosts";
1;
},
disabled => sub {
$daemonless_cups ||
(!$printer->{cupsconfig}{localprintersshared} &&
!$printer->{cupsconfig}{remotebroadcastsaccepted});
} },
{ val => N("Additional CUPS servers: ") .
($#{$browsepoll->{list}} >= 0 ?
($#{$browsepoll->{list}} > 1 ?
join(", ", @{$browsepoll->{list}}[0,1]) . " ..." :
join(", ", @{$browsepoll->{list}})) :
N("None")),
type => 'button',
help => N("To get access to printers on remote CUPS servers in your local network you only need to turn on the \"Automatically find available printers on remote machines\" option; the CUPS servers inform your machine automatically about their printers. All printers currently known to your machine are listed in the \"Remote printers\" section in the main window of Printerdrake. If your CUPS server(s) is/are not in your local network, you have to enter the IP address(es) and optionally the port number(s) here to get the printer information from the server(s)."),
clicked_may_quit => sub {
$buttonclicked = "browsepoll";
1;
},
disabled => sub {
$daemonless_cups;
} },
{ text => N("Japanese text printing mode"),
help => N("Turning on this allows to print plain text files in Japanese language. Only use this function if you really want to print text in Japanese, if it is activated you cannot print accentuated characters in latin fonts any more and you will not be able to adjust the margins, the character size, etc. This setting only affects printers defined on this machine. If you want to print Japanese text on a printer set up on a remote machine, you have to activate this function on that remote machine."),
type => 'bool',
val => \$jap_textmode,
disabled => sub {
$daemonless_cups;
} },
if_($printer->{expert},
{ text => N("Automatic correction of CUPS configuration"),
type => 'bool',
help => N("When this option is turned on, on every startup of CUPS it is automatically made sure that
- if LPD/LPRng is installed, /etc/printcap will not be overwritten by CUPS
- if /etc/cups/cupsd.conf is missing, it will be created
- when printer information is broadcasted, it does not contain \"localhost\" as the server name.
If some of these measures lead to problems for you, turn this option off, but then you have to take care of these points."),
val => \$printer->{cupsconfig}{autocorrection},
disabled => sub {
$daemonless_cups;
} }),
{ val => N("Remote CUPS server and no local CUPS daemon") .
": " .
($daemonless_cups ?
N("On") . "; " . N("Server") . ": " .
$remote_cups_server :
N("Off")),
help => N("In this mode the local CUPS daemon will be stopped and all printing requests go directly to the server specified below. Note that it is not possible to define local print queues then and if the specified server is down it cannot be printed at all from this machine."),
type => 'button',
clicked_may_quit => sub {
$buttonclicked = "daemonlesscups";
1;
} },
]
)
) {
if ($buttonclicked eq "sharehosts") {
# Show dialog to add hosts to share printers to
my $subdone = 0;
my $choice;
while (!$subdone) {
# Entry should be edited when double-clicked
$buttonclicked = "edit";
$in->ask_from_(
{ title => N("Sharing of local printers"),
messages => N("These are the machines and networks on which the locally connected printer(s) should be available:"),
ok => "",
cancel => "",
},
# List the hosts
[ { val => \$choice, format => \&translate,
sort => 0, separator => "####",
tree_expanded => 1,
quit_if_double_click => 1,
allow_empty_list => 1,
list => $sharehosts->{list} },
{ val => N("Add host/network"),
type => 'button',
clicked_may_quit => sub {
$buttonclicked = "add";
1;
} },
{ val => N("Edit selected host/network"),
type => 'button',
clicked_may_quit => sub {
$buttonclicked = "edit";
1;
},
disabled => sub {
return $#{$sharehosts->{list}} < 0;
} },
{ val => N("Remove selected host/network"),
type => 'button',
clicked_may_quit => sub {
$buttonclicked = "remove";
1;
},
disabled => sub {
return $#{$sharehosts->{list}} < 0;
} },
{ val => N("Done"),
type => 'button',
clicked_may_quit => sub {
$buttonclicked = "";
$subdone = 1;
1;
} },
]
);
if ($buttonclicked eq "add" ||
$buttonclicked eq "edit") {
my ($hostchoice, $ip);
if ($buttonclicked eq "add") {
# Use first entry as default for a new entry
$hostchoice = N("Local network(s)");
} else {
if ($sharehosts->{invhash}{$choice} =~ /^\@/) {
# Entry to edit is not an IP address
$hostchoice = $choice;
} else {
# Entry is an IP address
$hostchoice =
N("IP address of host/network:");
$ip = $sharehosts->{invhash}{$choice};
}
}
my @menu = N("Local network(s)");
my @interfaces =
printer::detect::getNetworkInterfaces();
foreach my $interface (@interfaces) {
push @menu, N("Interface \"%s\"", $interface);
}
push @menu, N("IP address of host/network:");
# Show the dialog
my $address;
my $oldaddress =
($buttonclicked eq "edit" ?
$sharehosts->{invhash}{$choice} : "");
if ($in->ask_from_(
{ title => N("Sharing of local printers"),
messages => N("Choose the network or host on which the local printers should be made available:"),
callbacks => {
complete => sub {
if ($hostchoice eq
N("IP address of host/network:") &&
$ip =~ /^\s*$/) {
$in->ask_warn(N("Error"), N("Host/network IP address missing."));
return 1, 1;
}
if ($hostchoice eq
N("IP address of host/network:") &&
!printer::main::is_network_ip($ip)) {
$in->ask_warn(N("Error"),
N("The entered host/network IP is not correct.\n") .
N("Examples for correct IPs:\n") .
"192.168.100.194\n" .
"10.0.0.*\n" .
"10.1.*\n" .
"192.168.100.0/24\n" .
"192.168.100.0/255.255.255.0\n"
);
return 1, 1;
}
if ($hostchoice eq $menu[0]) {
$address = '@LOCAL';
} elsif ($hostchoice eq $menu[-1]) {
$address = $ip;
} else {
($address) =
grep { $hostchoice =~ /$_/ }
@interfaces;
$address = "\@IF($address)";
}
# Check whether item is duplicate
if ($address ne $oldaddress &&
member($address,
@{$printer->{cupsconfig}{clientnetworks}})) {
$in->ask_warn(N("Error"),
N("This host/network is already in the list, it cannot be added again.\n"));
if ($hostchoice eq
N("IP address of host/network:")) {
return 1, 1;
} else {
return 1, 0;
}
}
return 0;
},
},
},
# List the host types
[ { val => \$hostchoice, format => \&translate,
type => 'list',
sort => 0,
list => \@menu },
{ val => \$ip,
disabled => sub {
$hostchoice ne
N("IP address of host/network:");
} },
],
)) {
# OK was clicked, insert new item into the list
if ($buttonclicked eq "add") {
push(@{$printer->{cupsconfig}{clientnetworks}},
$address);
} else {
@{$printer->{cupsconfig}{clientnetworks}} =
map { ($_ eq
$sharehosts->{invhash}{$choice} ?
$address : $_) }
@{$printer->{cupsconfig}{clientnetworks}};
}
# Refresh list of hosts
$sharehosts =
printer::main::makesharehostlist($printer);
# We have modified the configuration now
$printer->{cupsconfig}{customsharingsetup} = 0;
# Position the list cursor on the new/modified
# item
$choice = $sharehosts->{hash}{$address};
}
} elsif ($buttonclicked eq "remove") {
@{$printer->{cupsconfig}{clientnetworks}} =
grep { $_ ne $sharehosts->{invhash}{$choice} }
@{$printer->{cupsconfig}{clientnetworks}};
# Refresh list of hosts
$sharehosts =
printer::main::makesharehostlist($printer);
# We have modified the configuration now
$printer->{cupsconfig}{customsharingsetup} = 0;
}
}
# If we have no entry in the list, we do not
# share the local printers, mark this
if ($#{$printer->{cupsconfig}{clientnetworks}} < 0) {
$printer->{cupsconfig}{localprintersshared} = 0;
$printer->{cupsconfig}{remotebroadcastsaccepted} = 0;
}
} elsif ($buttonclicked eq "browsepoll") {
# Show dialog to add hosts to "BrowsePoll" from
my $subdone = 0;
my $choice;
while (!$subdone) {
# Entry should be edited when double-clicked
$buttonclicked = "edit";
$in->ask_from_(
{ title => N("Accessing printers on remote CUPS servers"),
messages => N("Add here the CUPS servers whose printers you want to use. You only need to do this if the servers do not broadcast their printer information into the local network."),
ok => "",
cancel => "",
},
# List the hosts
[ { val => \$choice, format => \&translate,
sort => 0, separator => "####",
tree_expanded => 1,
quit_if_double_click => 1,
allow_empty_list => 1,
list => $browsepoll->{list} },
{ val => N("Add server"),
type => 'button',
clicked_may_quit => sub {
$buttonclicked = "add";
1;
} },
{ val => N("Edit selected server"),
type => 'button',
clicked_may_quit => sub {
$buttonclicked = "edit";
1;
},
disabled => sub {
return $#{$browsepoll->{list}} < 0;
} },
{ val => N("Remove selected server"),
type => 'button',
clicked_may_quit => sub {
$buttonclicked = "remove";
1;
},
disabled => sub {
return $#{$browsepoll->{list}} < 0;
} },
{ val => N("Done"),
type => 'button',
clicked_may_quit => sub {
$buttonclicked = "";
$subdone = 1;
1;
} },
]
);
if ($buttonclicked eq "add" ||
$buttonclicked eq "edit") {
my ($ip, $port);
if ($buttonclicked eq "add") {
# Use default port
$port = '631';
} else {
if ($browsepoll->{invhash}{$choice} =~
/^([^:]+):([^:]+)$/) {
# Entry to edit has IP and port
$ip = $1;
$port = $2;
} else {
# Entry is only an IP, no port, so take
# the default port 631
$ip = $browsepoll->{invhash}{$choice};
$port = '631';
}
}
# Show the dialog
my $address;
my $oldaddress =
($buttonclicked eq "edit" ?
$browsepoll->{invhash}{$choice} : "");
if ($in->ask_from_(
{ title => N("Accessing printers on remote CUPS servers"),
messages => N("Enter IP address and port of the host whose printers you want to use.") . ' ' .
N("If no port is given, 631 will be taken as default."),
callbacks => {
complete => sub {
if ($ip =~ /^\s*$/) {
$in->ask_warn(N("Error"), N("Server IP missing!"));
return 1, 0;
}
if ($ip !~
/^\s*(\d+\.\d+\.\d+\.\d+)\s*$/) {
$in->ask_warn(N("Error"),
N("The entered IP is not correct.\n") .
N("Examples for correct IPs:\n") .
"192.168.100.194\n" .
"10.0.0.2\n"
);
return 1, 0;
} else {
$ip = $1;
}
if ($port !~ /\S/) {
$port = '631';
} elsif ($port !~ /^\s*(\d+)\s*$/) {
$in->ask_warn(N("Error"), N("The port number should be an integer!"));
return 1, 1;
} else {
$port = $1;
}
$address = "$ip:$port";
# Check whether item is duplicate
if ($address ne $oldaddress &&
member($address,
@{$printer->{cupsconfig}{BrowsePoll}})) {
$in->ask_warn(N("Error"),
N("This server is already in the list, it cannot be added again.\n"));
return 1, 0;
}
return 0;
},
},
},
# Ask for IP and port
[ { val => \$ip,
label => N("IP address") },
{ val => \$port,
label => N("Port") },
],
)) {
# OK was clicked, insert new item into the list
if ($buttonclicked eq "add") {
push(@{$printer->{cupsconfig}{BrowsePoll}},
$address);
} else {
@{$printer->{cupsconfig}{BrowsePoll}} =
map { ($_ eq
$browsepoll->{invhash}{$choice} ?
$address : $_) }
@{$printer->{cupsconfig}{BrowsePoll}};
}
# Refresh list of hosts
$browsepoll =
printer::main::makebrowsepolllist($printer);
# Position the list cursor on the new/modified
# item
$choice = $browsepoll->{hash}{$address};
}
} elsif ($buttonclicked eq "remove") {
@{$printer->{cupsconfig}{BrowsePoll}} =
grep { $_ ne $browsepoll->{invhash}{$choice} }
@{$printer->{cupsconfig}{BrowsePoll}};
# Refresh list of hosts
$browsepoll =
printer::main::makebrowsepolllist($printer);
}
}
} elsif ($buttonclicked eq "daemonlesscups") {
my ($modechoice, $rserver);
if ($daemonless_cups) {
$modechoice = N("On, Name or IP of remote server:");
$rserver = $remote_cups_server;
} else {
$modechoice = N("Off");
}
# Show the dialog
#my $address;
#my $oldaddress =
# ($buttonclicked eq "edit" ?
# $sharehosts->{invhash}{$choice} : "");
if ($in->ask_from_
({ title => N("Remote CUPS server and no local CUPS daemon"),
messages => N("In this mode the local CUPS daemon will be stopped and all printing requests go directly to the server specified below. Note that it is not possible to define local print queues then and if the specified server is down it cannot be printed at all from this machine."),
callbacks => {
complete => sub {
if ($modechoice eq
N("On, Name or IP of remote server:") &&
$rserver =~ /^\s*$/) {
$in->ask_warn(N("Error"), N("CUPS server name or IP address missing."));
return 1, 1;
}
return 0;
},
},
},
# Show the widgets
[ { val => \$modechoice, format => \&translate,
type => 'list',
sort => 0,
list => [ N("Off"),
N("On, Name or IP of remote server:") ]},
{ val => \$rserver,
disabled => sub {
$modechoice ne
N("On, Name or IP of remote server:");
} },
],
)) {
# OK was clicked, update the data
$daemonless_cups =
($modechoice eq N("On, Name or IP of remote server:"));
$remote_cups_server = $rserver;
}
} else {
# We have clicked "OK"
$retvalue = 1;
$maindone = 1;
# Write state for auto-correction of cupsd.conf
if ($oldautocorr !=
$printer->{cupsconfig}{autocorrection}) {
printer::main::set_cups_autoconf(
$printer->{cupsconfig}{autocorrection});
}
# Write state of japanese text printing mode
printer::main::set_jap_textmode($jap_textmode);
# Switch state of daemon-less CUPS mode and write
# client.conf
if (($daemonless_cups && $printer->{SPOOLER} ne "rcups") ||
(!$daemonless_cups && $printer->{SPOOLER} eq "rcups")) {
my $oldspooler = $printer->{SPOOLER};
$printer->{SPOOLER} = ($daemonless_cups ?
"rcups" : "cups");
if (install_spooler($printer, $security, $in->do_pkgs, $in, $upNetwork, 1)) {
printer::default::set_spooler($printer);
printer::main::write_client_conf
($daemonless_cups, $remote_cups_server);
$printer->{remote_cups_server} =
$remote_cups_server;
# Get the queues of this spooler
my $w = $in->wait_message
(N("Printerdrake"),
N("Reading printer data..."));
printer::main::read_configured_queues($printer);
undef $w;
# Re-read the printer database next time
%printer::main::thedb = ();
assure_default_printer_is_set($printer, $in);
} else {
$printer->{SPOOLER} = $oldspooler;
}
} elsif ($daemonless_cups) {
printer::main::write_client_conf($daemonless_cups,
$remote_cups_server);
$printer->{remote_cups_server} = $remote_cups_server;
} else {
undef $printer->{remote_cups_server};
}
# Write cupsd.conf
printer::main::write_cups_config($printer);
my $w =
$in->wait_message(N("Printerdrake"),
N("Restarting CUPS..."));
printer::main::write_cupsd_conf(
@{$printer->{cupsconfig}{cupsd_conf}});
#- restart cups after updating configuration.
printer::main::SIGHUP_daemon($printer->{SPOOLER});
undef $w;
}
} else {
# Cancel clicked
$maindone = 1;
}
}
printer::main::clean_cups_config($printer);
return $retvalue;
}
sub choose_printer_type {
my ($printer, $in, $upNetwork) = @_;
my $havelocalnetworks = check_network($printer, $in, $upNetwork, 1) &&
printer::detect::getIPsInLocalNetworks() != ();
$printer->{str_type} = $printer_type_inv{$printer->{TYPE}};
my $autodetect = 0;
$autodetect = 1 if $printer->{AUTODETECT};
my $timeout = 4000;
$timeout = $printer->{TIMEOUT} if defined($printer->{TIMEOUT});
my @printertypes = printer::main::printer_type($printer);
$in->ask_from_(
{ title => N("Select Printer Connection"),
messages => N("How is the printer connected?") .
if_($printer->{SPOOLER} eq "cups",
N("
Printers on remote CUPS servers do not need to be configured here; these printers will be automatically detected.")) .
if_(!$havelocalnetworks,
N("\nWARNING: No local network connection active, remote printers can neither be detected nor tested!")),
},
[
{ val => \$printer->{str_type},
list => \@printertypes,
not_edit => 1, sort => 0,
type => 'list' },
{ text => N("Printer auto-detection (Local, TCP/Socket, SMB printers, and device URI)"),
type => 'bool', val => \$autodetect },
{ val => N("Modify timeout for network printer auto-detection") ,
type => 'button',
clicked_may_quit => sub {
local $::isWizard = 0;
$in->ask_from_
({ title => N("Select Printer Connection"),
messages => N("Enter the timeout for network printer auto-detection (in msec) here. ") .
"\n\n" .
N("The longer you choose the timeout, the more reliable the detections of network printers will be, but the scan can take longer then, especially if there are many machines with local firewalls in the network. "),
callbacks => {
complete => sub {
if ($timeout !~ /^[0-9]+$/) {
$in->ask_warn(N("Error"), N("The timeout must be a positive integer number!"));
return 1, 0;
}
return 0;
}
}},
[ { val => \$timeout } ] );
0;
} },
],
) or return 0;
$printer->{TIMEOUT} = $timeout;
$printer->{AUTODETECT} = $autodetect ? 1 : undef;
$printer->{TYPE} = $printer_type{$printer->{str_type}};
1;
}
sub setup_printer_connection {
my ($printer, $in, $upNetwork) = @_;
# Choose the appropriate connection config dialog
my $done = 1;
for ($printer->{TYPE}) {
/LOCAL/ and setup_local_autoscan($printer, $in, $upNetwork) and last;
/LPD/ and setup_lpd( $printer, $in, $upNetwork) and last;
/SOCKET/ and setup_socket( $printer, $in, $upNetwork) and last;
/SMB/ and setup_smb( $printer, $in, $upNetwork) and last;
/NCP/ and setup_ncp( $printer, $in, $upNetwork) and last;
/URI/ and setup_uri( $printer, $in, $upNetwork) and last;
/POSTPIPE/ and setup_postpipe( $printer, $in) and last;
$done = 0; last;
}
return $done;
}
sub first_time_dialog {
my ($printer, $in, $upNetwork) = @_;
local $::isEmbedded = 0;
return 1 if printer::default::get_spooler() || $::isInstall;
my $w = $in->wait_message(N("Printerdrake"), N("Checking your system..."));
# Auto-detect local printers
my @autodetected = printer::detect::local_detect();
$printer->{AUTODETECTEDLOCALPRINTERSFIRSTTIME} = \@autodetected if @autodetected;
my $msg = do {
if (@autodetected) {
my @printerlist =
map {
my $entry = $_->{val}{DESCRIPTION};
$entry ||= "$_->{val}{MANUFACTURER} $_->{val}{MODEL}";
if_($entry, " - $entry\n");
} @autodetected;
my $unknown_printers = @autodetected - @printerlist;
if (@printerlist) {
my $unknown_msg =
$unknown_printers == 1 ?
"\n" . N("and one unknown printer") :
$unknown_printers > 1 ?
"\n" . N("and %d unknown printers", $unknown_printers) :
'';
my $main_msg =
@printerlist > 1 ?
N_("The following printers\n\n%s%s\nare directly connected to your system") :
$unknown_printers ?
N_("The following printer\n\n%s%s\nare directly connected to your system") :
N_("The following printer\n\n%s%s\nis directly connected to your system");
sprintf($main_msg, join('', @printerlist), $unknown_msg);
} else {
$unknown_printers == 1 ?
N("\nThere is one unknown printer directly connected to your system") :
N("\nThere are %d unknown printers directly connected to your system", $unknown_printers);
}
} else {
N("There are no printers found which are directly connected to your machine");
}
};
$msg .= N(" (Make sure that all your printers are connected and turned on).\n");
# Do we have a local network?
# If networking is configured, start it, but do not ask the user to
# configure networking.
my $havelocalnetworks =
check_network($printer, $in, $upNetwork, 1) &&
printer::detect::getIPsInLocalNetworks() != ();
# Finish building the dialog text
my $question = ($havelocalnetworks ?
(@autodetected ?
N("Do you want to enable printing on the printers mentioned above or on printers in the local network?\n") :
N("Do you want to enable printing on printers in the local network?\n")) :
(@autodetected ?
N("Do you want to enable printing on the printers mentioned above?\n") :
N("Are you sure that you want to set up printing on this machine?\n")));
my $warning = N("NOTE: Depending on the printer model and the printing system up to %d MB of additional software will be installed.", 80);
my $dialogtext = "$msg\n$question\n$warning";
# Close wait message
undef $w;
while (1) {
# Show dialog
my $do_it = N("Yes");
my $quit = N("Quit");
my @choices = ($do_it, $quit);
my $choice = $in->ask_from_list(N("Printerdrake"), $dialogtext,
\@choices, $quit);
return 0 if $choice ne $do_it;
if ($havelocalnetworks && !@autodetected ) {
return set_cups_daemon_mode($printer, $in);
} else {
$printer->{SPOOLER} = "cups";
return 1;
}
}
}
sub configure_new_printers {
my ($printer, $in, $_upNetwork) = @_;
# This procedure auto-detects local printers and checks whether
# there is already a queue for them. If there is no queue for an
# auto-detected printer, a queue gets set up non-interactively.
# Experts can have weird things as self-made CUPS backends, so do not
# automatically pollute the system with unwished queues in expert
# mode
return 1 if $printer->{expert};
# Wait message
my $w = $::noX ||
$in->wait_message(N("Printerdrake"),
N("Searching for new printers..."));
# When HPOJ is running, it blocks the printer ports on which it is
# configured, so we stop it here. If it is not installed or not
# configured, this command has no effect. We do not stop HPOJ if we are
# called by the hotplug script, as HPOJ reloads the parallel port
# kernel modules and causes a new hotplug signal which leads to
# recursive calls of the hotplug script.
require services;
services::stop("hpoj") if !$::noX;
# Auto-detect local printers
my @autodetected = printer::detect::local_detect();
$printer->{AUTODETECTEDPRINTERSNONINTERACTIVE} = \@autodetected if @autodetected;
# We are ready with auto-detection, so we restart HPOJ here. If it
# is not installed or not configured, this command has no effect.
services::start("hpoj") if !$::noX;
# No printer found? So no need of new queues.
return 1 if !@autodetected;
# Black-list all auto-detected printers for which there is already
# a queue
my @blacklist;
foreach my $queue (keys %{$printer->{configured}}) {
# Does the URI of this installed queue match one of the autodetected
# printers?
my $uri = $printer->{configured}{$queue}{queuedata}{connect};
my $p = printer::main::autodetectionentry_for_uri(
$uri, @autodetected);
if (defined($p)) {
# Blacklist the port
push(@blacklist, $p->{port});
}
}
# Now install queues for all auto-detected printers which have no queue
# yet
$printer->{noninteractive} = 1; # Suppress all interactive steps
foreach my $p (@autodetected) {
if (!member($p->{port}, @blacklist)) {
# Initialize some variables for queue setup
$printer->{NEW} = 1;
$printer->{TYPE} = "LOCAL";
$printer->{currentqueue} = { queue => "",
foomatic => 0,
desc => "",
loc => "",
make => "",
model => "",
printer => "",
driver => "",
connect => "",
spooler => $printer->{SPOOLER},
};
undef $w;
$w = $::noX ||
$in->wait_message(N("Printerdrake"),
N("Found printer on %s...",
$p->{port}));
# Do configuration of multi-function devices and look up
# model name in the printer database
setup_common($printer, $in, $p->{val}{DESCRIPTION}, $p->{port},
1, @autodetected) or next;
# Do the steps of queue setup
get_db_entry($printer, $in);
# Let the user choose the model manually if it could not be
# auto-detected.
if (!$printer->{DBENTRY}) {
# Skip this printer if we install print queues in a
# background without X access.
if ($::noX) {
# Delete some variables
foreach (qw(OLD_QUEUE QUEUE TYPE str_type DBENTRY ARGS OLD_CHOICE currentqueue NEW)) {
$printer->{$_} = "";
}
next;
}
# Set the OLD_CHOICE to a non-existing value
$printer->{OLD_CHOICE} = "XXX";
# Set model selection cursor onto the "Raw Printer" entry.
$printer->{DBENTRY} = N("Raw printer (No driver)");
# Info about what was detected
my $info = N("(") . if_($p->{val}{DESCRIPTION},
$p->{val}{DESCRIPTION} . N(" on ")) .
$p->{port} . N(")");
# Remove wait message
undef $w;
# Choose the printer/driver from the list
$printer->{DBENTRY} =
$in->ask_from_treelist(N("Printer model selection"),
N("Which printer model do you have?") .
N("
Printerdrake could not determine which model your printer %s is. Please choose the correct model from the list.", $info) . " " .
N("If your printer is not listed, choose a compatible (see printer manual) or a similar one."), '|',
[ keys %printer::main::thedb ], $printer->{DBENTRY}) or next;
# Restore wait message
$w = $::noX ||
$in->wait_message(N("Printerdrake"),
N("Configuring printer on %s...",
$p->{port}));
}
get_printer_info($printer, $in) or next;
setup_options($printer, $in) or next;
my $_queue = generate_queuename($printer);
# Change wait message
undef $w;
$w = $::noX ||
$in->wait_message(N("Printerdrake"),
N("Configuring printer \"%s\"...",
$printer->{currentqueue}{queue}));
# Create the queue
configure_queue($printer, $in) or next;
# If there is no default printer set, let this one get the
# default
if (!$printer->{DEFAULT}) {
$printer->{DEFAULT} = $printer->{QUEUE};
printer::default::set_printer($printer);
}
}
# Delete some variables
foreach (qw(OLD_QUEUE QUEUE TYPE str_type DBENTRY ARGS OLD_CHOICE)) {
$printer->{$_} = "";
}
$printer->{currentqueue} = {};
$printer->{complete} = 0;
}
undef $printer->{noninteractive};
}
sub generate_queuename {
my ($printer) = @_;
my $queue;
if ($printer->{currentqueue}{model}) {
if ($printer->{currentqueue}{model} eq N("Unknown model")) {
$queue = "P";
} else {
$queue = $printer->{currentqueue}{make} . '|' .
$printer->{currentqueue}{model};
}
} else {
$queue = $printer->{DBENTRY};
}
$queue =~ s/\|/ /g;
$printer->{currentqueue}{desc} = $queue;
$queue =~ s/series//gi;
$queue =~ s/[\s\(\)\-,]//g;
my $make = $printer->{currentqueue}{make};
my $model = $printer->{currentqueue}{model};
$queue =~ s/$make$make/$make/gi;
# Remove weird characters
$queue =~ s/[^A-Za-z0-9_]//g;
$make =~ s/[^A-Za-z0-9_]//g;
$model =~ s/[^A-Za-z0-9_]//g;
# Do not use a queue name longer than 12 characters, as otherwise
# Windows clients will not be able to access the printer
my $ml = 12;
if (length($queue) > $ml) {
my %parts;
$parts{'make'} = $make;
$parts{'model'} = $model;
# Go through the two components, begin with model name, then
# make and then driver
for my $part (qw/model make/) {
$parts{$part} =~ s/[^a-zA-Z0-9_]/ /g;
# Split the component into words, cutting always at the
# right edge of the word. Cut also at a capital in the
# middle of the word (ex: "S" in "PostScript").
my @words =
split(/(?<=[a-zA-Z])(?![a-zA-Z])|(?<=[a-z])(?=[A-Z])/,
$parts{$part});
# Go through all words
for (@words) {
# Do not abbreviate words of less than 3 letters
next if ($_ !~ /[a-zA-Z]{3,}$/);
while (1) {
# Remove the last letter
chop;
# Build the shortened component ...
$parts{$part} = join('', @words);
# ... and the queue name
$queue = "$parts{'make'} $parts{'model'}";
$queue =~ s/\s+//g;
# Stop if the queue name has 12 characters or
# less, if there is only one letter left, or if
# the manufacturer name is reduced to three
# characters.
last if ((length($queue) <= $ml) ||
($_ !~ /[a-zA-Z]{2,}$/) ||
(length($parts{'make'}) <= 3));
}
$parts{$part} = join('', @words);
$queue = "$parts{'make'} $parts{'model'}";
$queue =~ s/\s+//g;
last if (length($queue) <= $ml);
}
last if (length($queue) <= $ml);
}
while ((length($queue) > $ml) &&
(length($parts{'model'}) > 3)) {
# Queue name too long? Remove last words from model name.
$parts{'model'} =~
s/(?<=[a-zA-Z0-9])[^a-zA-Z0-9]+[a-zA-Z0-9]*$//;
$queue = "$parts{'make'} $parts{'model'}";
$queue =~ s/\s+//g;
}
if (length($queue) > $ml) {
# If nothing else helps ...
$queue = substr($queue, 0, $ml);
}
}
# Append a number if the queue name already exists
if ($printer->{configured}{$queue}) {
my $origname = $queue;
my $i = 1;
while (1) {
my $ol = length($origname);
my $nl = length($i);
my $us = ($origname =~ m/\d$/ ? 1 : 0);
if ($ol + $nl + $us <= $ml) {
$queue = $origname . ($us ? '_' : '') . $i;
} else {
$queue = substr($queue, 0, $ml - $nl);
$queue =~ s/\d$/_/;
$queue .= $i;
}
last if (!$printer->{configured}{$queue});
$i ++;
}
}
$printer->{currentqueue}{queue} = $queue;
$printer->{OLD_QUEUE} = $printer->{QUEUE} = $queue;
return $queue;
}
sub wizard_welcome {
my ($printer, $in, $upNetwork) = @_;
local $::isEmbedded = 0;
my $ret;
my $autodetectlocal = 0;
my $autodetectnetwork = 0;
my $autodetectsmb = 0;
my $configlpd = 0;
# If networking is configured, start it, but do not ask the user to
# configure networking.
my $havelocalnetworks;
if ($printer->{expert}) {
$havelocalnetworks = 0;
undef $printer->{AUTODETECTNETWORK};
undef $printer->{AUTODETECTSMB};
} else {
$havelocalnetworks = check_network($printer, $in, $upNetwork, 1) &&
printer::detect::getIPsInLocalNetworks() != ();
if (!$havelocalnetworks) {
undef $printer->{AUTODETECTNETWORK};
undef $printer->{AUTODETECTSMB};
}
$autodetectlocal = 1 if $printer->{AUTODETECTLOCAL};
$autodetectnetwork = 1 if $printer->{AUTODETECTNETWORK};
$autodetectsmb = 1 if $printer->{AUTODETECTSMB};
$configlpd = 1 if $printer->{CONFIGLPD};
}
my $oldautodetectlocal = $autodetectlocal;
my $oldautodetectnetwork = $autodetectnetwork;
my $oldautodetectsmb = $autodetectsmb;
my $oldconfiglpd = $configlpd;
if ($in) {
eval {
if ($printer->{expert}) {
if ($::isWizard) {
$ret = $in->ask_okcancel(
N("Add a new printer"),
N("
Welcome to the Printer Setup Wizard
This wizard allows you to install local or remote printers to be used from this machine and also from other machines in the network.
It asks you for all necessary information to set up the printer and gives you access to all available printer drivers, driver options, and printer connection types."));
} else {
$ret = 1;
}
} else {
$ret = $in->ask_from_(
{ title => N("Add a new printer"),
messages => ($printer->{SPOOLER} ne "pdq" ?
($havelocalnetworks ? N("
Welcome to the Printer Setup Wizard
This wizard will help you to install your printer(s) connected to this computer, connected directly to the network or to a remote Windows machine.
Please plug in and turn on all printers connected to this machine so that it/they can be auto-detected. Also your network printer(s) and your Windows machines must be connected and turned on.
Note that auto-detecting printers on the network takes longer than the auto-detection of only the printers connected to this machine. So turn off the auto-detection of network and/or Windows-hosted printers when you do not need it.
Click on \"Next\" when you are ready, and on \"Cancel\" if you do not want to set up your printer(s) now.") : N("
Welcome to the Printer Setup Wizard
This wizard will help you to install your printer(s) connected to this computer.
Please plug in and turn on all printers connected to this machine so that it/they can be auto-detected.
Click on \"Next\" when you are ready, and on \"Cancel\" if you do not want to set up your printer(s) now.")) :
($havelocalnetworks ? N("
Welcome to the Printer Setup Wizard
This wizard will help you to install your printer(s) connected to this computer or connected directly to the network.
If you have printer(s) connected to this machine, Please plug it/them in on this computer and turn it/them on so that it/they can be auto-detected. Also your network printer(s) must be connected and turned on.
Note that auto-detecting printers on the network takes longer than the auto-detection of only the printers connected to this machine. So turn off the auto-detection of network printers when you do not need it.
Click on \"Next\" when you are ready, and on \"Cancel\" if you do not want to set up your printer(s) now.") : N("
Welcome to the Printer Setup Wizard
This wizard will help you to install your printer(s) connected to this computer.
If you have printer(s) connected to this machine, Please plug it/them in on this computer and turn it/them on so that it/they can be auto-detected.
Click on \"Next\" when you are ready, and on \"Cancel\" if you do not want to set up your printer(s) now."))),
callbacks => {
changed => sub {
if ($oldautodetectlocal ne
$autodetectlocal) {
if ($autodetectlocal) {
$configlpd = 0;
$oldconfiglpd = 0;
}
$oldautodetectlocal = $autodetectlocal;
}
if ($oldautodetectnetwork ne
$autodetectnetwork) {
if ($autodetectnetwork) {
$configlpd = 0;
$oldconfiglpd = 0;
}
$oldautodetectnetwork =
$autodetectnetwork;
}
if ($oldautodetectsmb ne
$autodetectsmb) {
if ($autodetectsmb) {
$configlpd = 0;
$oldconfiglpd = 0;
}
$oldautodetectsmb = $autodetectsmb;
}
if ($oldconfiglpd ne $configlpd) {
if ($configlpd) {
$autodetectlocal = 0;
$autodetectnetwork = 0;
$autodetectsmb = 0;
$oldautodetectlocal = 0;
$oldautodetectnetwork = 0;
$oldautodetectsmb = 0;
}
$oldconfiglpd = $configlpd;
}
return 0;
}
}
},
[
{ text => N("Auto-detect printers connected to this machine"), type => 'bool',
val => \$autodetectlocal },
if_($havelocalnetworks,
{ text => N("Auto-detect printers connected directly to the local network"), type => 'bool',
val => \$autodetectnetwork },
if_($printer->{SPOOLER} ne "pdq",
{ text => N("Auto-detect printers connected to machines running Microsoft Windows"), type => 'bool',
val => \$autodetectsmb },
{ text => N("Printer on remote lpd server")
. " (" . N("No auto-detection") . ")",
type => 'bool',
val => \$configlpd })),
]);
$printer->{AUTODETECTLOCAL} = $autodetectlocal ? 1 : undef;
$printer->{AUTODETECTNETWORK} = $autodetectnetwork ? 1 : undef;
$printer->{AUTODETECTSMB} = $autodetectsmb && $printer->{SPOOLER} ne "pdq" ? 1 : undef;
$printer->{CONFIGLPD} = $configlpd ? 1 : undef;
$printer->{TIMEOUT} = 4000;
}
};
return $@ =~ /wizcancel/ ? 0 : $ret;
}
}
sub wizard_congratulations {
my ($in) = @_;
local $::isEmbedded = 0;
if ($in) {
$in->ask_okcancel(N("Add a new printer"),
N("
Congratulations, your printer is now installed and configured!
You can print using the \"Print\" command of your application (usually in the \"File\" menu).
If you want to add, remove, or rename a printer, or if you want to change the default option settings (paper input tray, printout quality, ...), select \"Printer\" in the \"Hardware\" section of the %s Control Center.", $shortdistroname))
}
}
sub setup_local_autoscan {
my ($printer, $in, $upNetwork) = @_;
local $::isEmbedded = 0;
my $queue = $printer->{OLD_QUEUE};
my $expert_or_modify = $printer->{expert} || !$printer->{NEW};
my $do_auto_detect =
($expert_or_modify &&
$printer->{AUTODETECT} ||
(!$expert_or_modify &&
($printer->{AUTODETECTLOCAL} ||
$printer->{AUTODETECTNETWORK} ||
$printer->{AUTODETECTSMB})));
# If the user requested auto-detection of remote printers, check
# whether the network functionality is configured and running
if ($printer->{AUTODETECTNETWORK} || $printer->{AUTODETECTSMB}) {
return 0 unless check_network($printer, $in, $upNetwork, 0);
}
my @autodetected;
my $menuentries = {};
# $in->set_help('setupLocal') if $::isInstall;
if ($do_auto_detect) {
if (!$::testing &&
!$expert_or_modify && $printer->{AUTODETECTSMB} && !files_exist('/usr/bin/smbclient')) {
$in->do_pkgs->install('samba-client') or do {
$in->ask_warn(N("Warning"),
N("Could not install the %s packages!",
"Samba client") . " " .
N("Skipping Windows/SMB server auto-detection"));
$printer->{AUTODETECTSMB} = 0;
return 0 if !$printer->{AUTODETECTLOCAL} &&
!$printer->{AUTODETECTNETWORK};
};
}
my $_w = $in->wait_message(N("Printer auto-detection"), N("Detecting devices..."));
# When HPOJ is running, it blocks the printer ports on which it is
# configured, so we stop it here. If it is not installed or not
# configured, this command has no effect.
require services;
services::stop("hpoj");
@autodetected = (
$expert_or_modify || $printer->{AUTODETECTLOCAL} ? printer::detect::local_detect() : (),
!$expert_or_modify ? printer::detect::whatNetPrinter($printer->{AUTODETECTNETWORK}, $printer->{AUTODETECTSMB}, $printer->{TIMEOUT}) : (),
);
$printer->{AUTODETECTEDPRINTERSADDPRINTERSTANDARD} = \@autodetected if @autodetected;
# We have more than one printer, so we must ask the user for a queue
# name in the fully automatic printer configuration.
$printer->{MORETHANONE} = $#autodetected > 0;
my @str;
foreach my $p (@autodetected) {
if (($p->{val}{DESCRIPTION}) || ($p->{val}{MODEL})) {
my $menustr = ($p->{val}{DESCRIPTION} ?
$p->{val}{DESCRIPTION} :
(($p->{val}{MANUFACTURER} ?
($p->{val}{MANUFACTURER} . " ") : ()) .
$p->{val}{MODEL}));
if ($p->{port} =~ m!^/dev/lp(\d+)$!) {
my $port = $1;
$menustr .= N(" on parallel port #%s", $port);
} elsif ($p->{port} =~ m!^/dev/usb/lp(\d+)$!) {
my $printer = $1;
$menustr .= N(", USB printer #%s", $printer);
} elsif ($p->{port} =~ m!^socket://([^:]+):(\d+)$!) {
my ($printer, $port) = ($1, $2);
$menustr .= N(", network printer \"%s\", port %s", $printer, $port);
} elsif ($p->{port} =~ m!^smb://([^/:]+)/([^/:]+)$!) {
my ($server, $printer) = ($1, $2);
$menustr .= N(", printer \"%s\" on SMB/Windows server \"%s\"", $printer, $server);
}
$menustr .= " ($p->{port})" if $printer->{expert};
$menuentries->{$menustr} = $p->{port};
push @str, N("Detected %s", $menustr);
} else {
my $menustr;
if ($p->{port} =~ m!^/dev/lp(\d+)$!) {
my $port = $1;
$menustr = N("Printer on parallel port #%s", $port);
} elsif ($p->{port} =~ m!^/dev/usb/lp(\d+)$!) {
my $printer = $1;
$menustr = N("USB printer #%s", $printer);
} elsif ($p->{port} =~ m!^socket://([^:]+):(\d+)$!) {
my ($printer, $port);
$menustr .= N("Network printer \"%s\", port %s", $printer, $port);
} elsif ($p->{port} =~ m!^smb://([^/:]+)/([^/:]+)$!) {
my ($server, $printer) = ($1, $2);
$menustr .= N("Printer \"%s\" on SMB/Windows server \"%s\"", $printer, $server);
}
$menustr .= " ($p->{port})" if $printer->{expert};
$menuentries->{$menustr} = $p->{port};
}
}
my @port;
if ($printer->{expert}) {
@port = printer::detect::whatPrinterPort();
LOOP: foreach my $q (@port) {
if (@str) {
foreach my $p (@autodetected) {
last LOOP if $p->{port} eq $q;
}
}
my $menustr;
if ($q =~ m!^/dev/lp(\d+)$!) {
my $port = $1;
$menustr = N("Printer on parallel port #%s", $port);
} elsif ($q =~ m!^/dev/usb/lp(\d+)$!) {
my $printer;
$menustr = N("USB printer #%s", $printer);
}
$menustr .= " ($q)" if $printer->{expert};
$menuentries->{$menustr} = $q;
}
}
# We are ready with auto-detection, so we restart HPOJ here. If it
# is not installed or not configured, this command has no effect.
printer::services::start("hpoj");
} else {
# Always ask for queue name in recommended mode when no auto-
# detection was done
$printer->{MORETHANONE} = $#autodetected > 0;
my $m;
for ($m = 0; $m <= 2; $m++) {
my $menustr = N("Printer on parallel port #%s", $m);
$menustr .= " (/dev/lp$m)" if $printer->{expert};
$menuentries->{$menustr} = "/dev/lp$m";
$menustr = N("USB printer #%s", $m);
$menustr .= " (/dev/usb/lp$m)" if $printer->{expert};
$menuentries->{$menustr} = "/dev/usb/lp$m";
}
}
my @menuentrieslist = sort {
my @prefixes = ("/dev/lp", "/dev/usb/lp", "/dev/", "socket:",
"smb:");
my $first = $menuentries->{$a};
my $second = $menuentries->{$b};
for (my $i = 0; $i <= $#prefixes; $i++) {
my $firstinlist = $first =~ m!^$prefixes[$i]!;
my $secondinlist = $second =~ m!^$prefixes[$i]!;
if ($firstinlist && !$secondinlist) { return -1 };
if ($secondinlist && !$firstinlist) { return 1 };
}
return $first cmp $second;
} keys(%$menuentries);
my $menuchoice = "";
my $oldmenuchoice = "";
my $device;
if ($printer->{configured}{$queue}) {
my $p = printer::main::autodetectionentry_for_uri(
$printer->{currentqueue}{connect}, @autodetected);
if (defined($p)) {
$device = $p->{port};
$menuchoice = { reverse %$menuentries }->{$device};
}
}
if ($menuchoice eq "" && @menuentrieslist > -1) {
$menuchoice = $menuentrieslist[0];
$oldmenuchoice = $menuchoice;
$device = $menuentries->{$menuchoice} if $device eq "";
}
if ($in) {
# $printer->{expert} or $in->set_help('configurePrinterDev') if $::isInstall;
if ($#menuentrieslist < 0) { # No menu entry
# auto-detection has failed, we must do all manually
$do_auto_detect = 0;
$printer->{MANUAL} = 1;
if ($printer->{expert}) {
$device = $in->ask_from_entry(
N("Local Printer"),
N("No local printer found! To manually install a printer enter a device name/file name in the input line (Parallel Ports: /dev/lp0, /dev/lp1, ..., equivalent to LPT1:, LPT2:, ..., 1st USB printer: /dev/usb/lp0, 2nd USB printer: /dev/usb/lp1, ...)."),
{
complete => sub {
if ($menuchoice eq "") {
$in->ask_warn(N("Error"), N("You must enter a device or file name!"));
return 1, 0;
}
return 0;
}
});
return 0 if $device eq "";
} else {
$in->ask_warn(N("Printer auto-detection"),
N("No printer found!"));
return 0;
}
} else {
my $manualconf = 0;
$manualconf = 1 if $printer->{MANUAL} || !$do_auto_detect;
if (!$in->ask_from_(
{ title => ($expert_or_modify ?
N("Local Printers") :
N("Available printers")),
messages => (($do_auto_detect ?
($printer->{expert} ?
(@menuentrieslist == 1 ?
(N("The following printer was auto-detected. ") .
($printer->{NEW} ?
N("If it is not the one you want to configure, enter a device name/file name in the input line") :
N("Alternatively, you can specify a device name/file name in the input line"))) :
(N("Here is a list of all auto-detected printers. ") .
($printer->{NEW} ?
N("Please choose the printer you want to set up or enter a device name/file name in the input line") :
N("Please choose the printer to which the print jobs should go or enter a device name/file name in the input line")))) :
(@menuentrieslist == 1 ?
(N("The following printer was auto-detected. ") .
($printer->{NEW} ?
N("The configuration of the printer will work fully automatically. If your printer was not correctly detected or if you prefer a customized printer configuration, turn on \"Manual configuration\".") :
N("Currently, no alternative possibility is available"))) :
(N("Here is a list of all auto-detected printers. ") .
($printer->{NEW} ?
N("Please choose the printer you want to set up. The configuration of the printer will work fully automatically. If your printer was not correctly detected or if you prefer a customized printer configuration, turn on \"Manual configuration\".") :
N("Please choose the printer to which the print jobs should go."))))) :
($printer->{expert} ?
N("Please choose the port that your printer is connected to or enter a device name/file name in the input line") :
N("Please choose the port that your printer is connected to."))) .
if_($printer->{expert},
N(" (Parallel Ports: /dev/lp0, /dev/lp1, ..., equivalent to LPT1:, LPT2:, ..., 1st USB printer: /dev/usb/lp0, 2nd USB printer: /dev/usb/lp1, ...)."))),
callbacks => {
complete => sub {
unless ($menuchoice ne "") {
$in->ask_warn(N("Error"), N("You must choose/enter a printer/device!"));
return 1, 0;
}
return 0;
},
changed => sub {
if ($oldmenuchoice ne $menuchoice) {
$device = $menuentries->{$menuchoice};
$oldmenuchoice = $menuchoice;
}
return 0;
}
} },
[
if_($printer->{expert}, { val => \$device }),
{ val => \$menuchoice, list => \@menuentrieslist,
not_edit => !$printer->{expert}, format => \&translate,
allow_empty_list => 1, type => 'list' },
if_(!$printer->{expert} && $do_auto_detect && $printer->{NEW},
{ text => N("Manual configuration"), type => 'bool',
val => \$manualconf }),
]
)) {
return 0;
}
if ($device ne $menuentries->{$menuchoice}) {
$menuchoice = "";
$do_auto_detect = 0;
}
$printer->{MANUAL} = $manualconf ? 1 : undef;
}
}
#- LPD and LPRng need netcat ('nc') to access to socket printers
if (($printer->{SPOOLER} eq 'lpd' || $printer->{SPOOLER} eq 'lprng') &&
!$::testing && $device =~ /^socket:/ && !files_exist('/usr/bin/nc')) {
$in->do_pkgs->install('nc') or do {
$in->ask_warn(N("Error"),
N("Could not install the %s packages!",
"nc") . " " .
N("Aborting"));
return 0;
};
}
# Do configuration of multi-function devices and look up model name
# in the printer database
setup_common($printer, $in, $menuchoice, $device, $do_auto_detect,
@autodetected);
1;
}
sub setup_lpd {
my ($printer, $in, $upNetwork) = @_;
local $::isEmbedded = 0;
# Check whether the network functionality is configured and
# running
if (!check_network($printer, $in, $upNetwork, 0)) { return 0 };
# $in->set_help('setupLPD') if $::isInstall;
my ($uri, $remotehost, $remotequeue);
my $queue = $printer->{OLD_QUEUE};
if ($printer->{configured}{$queue} &&
$printer->{currentqueue}{connect} =~ m/^lpd:/) {
$uri = $printer->{currentqueue}{connect};
if ($uri =~ m!^\s*lpd://([^/]+)/([^/]+)/?\s*$!) {
$remotehost = $1;
$remotequeue = $2;
}
} else {
$remotehost = "";
$remotequeue = "lp";
}
return if !$in->ask_from(N("Remote lpd Printer Options"),
N("To use a remote lpd printer, you need to supply the hostname of the printer server and the printer name on that server."), [
{ label => N("Remote host name"), val => \$remotehost },
{ label => N("Remote printer name"), val => \$remotequeue } ],
complete => sub {
if ($remotehost eq "") {
$in->ask_warn(N("Error"), N("Remote host name missing!"));
return 1, 0;
}
if ($remotequeue eq "") {
$in->ask_warn(N("Error"), N("Remote printer name missing!"));
return 1, 1;
}
return 0;
}
);
#- make the DeviceURI from user input.
$printer->{currentqueue}{connect} = "lpd://$remotehost/$remotequeue";
#- LPD does not support filtered queues to a remote LPD server by itself
#- It needs an additional program as "rlpr"
if ($printer->{SPOOLER} eq 'lpd' && !$::testing &&
!files_exist('/usr/bin/rlpr')) {
$in->do_pkgs->install('rlpr') or do {
$in->ask_warn(N("Error"),
N("Could not install the %s packages!",
"rlpr") . " " .
N("Aborting"));
return 0;
};
}
# Auto-detect printer model (works if host is an ethernet-connected
# printer)
my $modelinfo = printer::detect::getSNMPModel($remotehost);
my $auto_hpoj;
if (defined($modelinfo) &&
$modelinfo->{MANUFACTURER} ne "" &&
$modelinfo->{MODEL} ne "") {
local $::isWizard = 0;
$in->ask_warn(N("Information"), N("Detected model: %s %s",
$modelinfo->{MANUFACTURER}, $modelinfo->{MODEL}));
$auto_hpoj = 1;
} else {
$auto_hpoj = 0;
}
# Do configuration of multi-function devices and look up model name
# in the printer database
setup_common($printer, $in,
"$modelinfo->{MANUFACTURER} $modelinfo->{MODEL}",
$printer->{currentqueue}{connect}, $auto_hpoj,
({port => $printer->{currentqueue}{connect},
val => $modelinfo }));
1;
}
sub setup_smb {
my ($printer, $in, $upNetwork) = @_;
local $::isEmbedded = 0;
# Check whether the network functionality is configured and
# running
if (!check_network($printer, $in, $upNetwork, 0)) { return 0 };
# $in->set_help('setupSMB') if $::isInstall;
my ($uri, $smbuser, $smbpassword, $workgroup, $smbserver, $smbserverip, $smbshare);
my $queue = $printer->{OLD_QUEUE};
if ($printer->{configured}{$queue} &&
$printer->{currentqueue}{connect} =~ m/^smb:/) {
$uri = $printer->{currentqueue}{connect};
my $parameters = $1 if $uri =~ m!^\s*smb://(.*)$!;
# Get the user's login and password from the URI
if ($parameters =~ m!([^@]*)@([^@]+)!) {
my $login = $1;
$parameters = $2;
if ($login =~ m!([^:]*):([^:]*)!) {
$smbuser = $1;
$smbpassword = $2;
} else {
$smbuser = $login;
$smbpassword = "";
}
} else {
$smbuser = "";
$smbpassword = "";
}
# Get the workgroup, server, and share name
if ($parameters =~ m!([^/]*)/([^/]+)/([^/]+)$!) {
$workgroup = $1;
$smbserver = $2;
$smbshare = $3;
} elsif ($parameters =~ m!([^/]+)/([^/]+)$!) {
$workgroup = "";
$smbserver = $1;
$smbshare = $2;
} else {
die qq(The "smb://" URI must at least contain the server name and the share name!\n);
}
if (is_ip($smbserver)) {
$smbserverip = $smbserver;
$smbserver = "";
}
}
my $autodetect = 0;
my @autodetected;
my $menuentries;
my @menuentrieslist;
my $menuchoice = "";
my $oldmenuchoice = "";
if ($printer->{AUTODETECT}) {
$autodetect = 1;
if (!$::testing && !files_exist('/usr/bin/smbclient')) {
$in->do_pkgs->install('samba-client') or do {
$in->ask_warn(N("Error"),
N("Could not install the %s packages!",
"Samba client") . " " .
N("Aborting"));
return 0;
};
}
my $_w = $in->wait_message(N("Printer auto-detection"), N("Scanning network..."));
@autodetected = printer::detect::net_smb_detect($printer->{TIMEOUT});
$printer->{AUTODETECTEDPRINTERSADDPRINTEREXPERTSMB} = \@autodetected if @autodetected;
my ($server, $share);
foreach my $p (@autodetected) {
my $menustr;
if ($p->{port} =~ m!^smb://([^/:]+)/([^/:]+)$!) {
$server = $1;
$share = $2;
}
if ($p->{val}{DESCRIPTION}) {
$menustr = $p->{val}{DESCRIPTION};
$menustr .= N(", printer \"%s\" on server \"%s\"",
$share, $server);
} else {
$menustr = N("Printer \"%s\" on server \"%s\"",
$share, $server);
}
$menuentries->{$menustr} = $p->{port};
if ($server eq $smbserver &&
$share eq $smbshare) {
$menuchoice = $menustr;
}
}
@menuentrieslist = sort {
$menuentries->{$a} cmp $menuentries->{$b};
} keys(%$menuentries);
if ($printer->{configured}{$queue} &&
$printer->{currentqueue}{connect} =~ m/^smb:/ &&
$menuchoice eq "") {
my $menustr;
if ($printer->{currentqueue}{make}) {
$menustr = "$printer->{currentqueue}{make} $printer->{currentqueue}{model}";
$menustr .= N(", printer \"%s\" on server \"%s\"",
$smbshare, $smbserver);
} else {
$menustr = N("Printer \"%s\" on server \"%s\"",
$smbshare, $smbserver);
}
$menuentries->{$menustr} = "smb://$smbserver/$smbshare";
unshift(@menuentrieslist, $menustr);
$menuchoice = $menustr;
}
if ($#menuentrieslist < 0) {
$autodetect = 0;
} elsif ($menuchoice eq "") {
$menuchoice = $menuentrieslist[0];
if ($menuentries->{$menuentrieslist[0]} =~
m!^smb://([^/:]+)/([^/:]+)$!) {
$smbserver = $1;
$smbshare = $2;
}
}
$oldmenuchoice = $menuchoice;
}
return 0 if !$in->ask_from(
N("SMB (Windows 9x/NT) Printer Options"),
N("To print to a SMB printer, you need to provide the SMB host name (Note! It may be different from its TCP/IP hostname!) and possibly the IP address of the print server, as well as the share name for the printer you wish to access and any applicable user name, password, and workgroup information.") .
($autodetect ? N(" If the desired printer was auto-detected, simply choose it from the list and then add user name, password, and/or workgroup if needed.") : ""),
[
{ label => N("SMB server host"), val => \$smbserver },
{ label => N("SMB server IP"), val => \$smbserverip },
{ label => N("Share name"), val => \$smbshare },
{ label => N("User name"), val => \$smbuser },
{ label => N("Password"), val => \$smbpassword, hidden => 1 },
{ label => N("Workgroup"), val => \$workgroup },
if_($autodetect,
{ label => N("Auto-detected"),
val => \$menuchoice, list => \@menuentrieslist,
not_edit => 1, format => \&translate, sort => 0,
allow_empty_list => 1, type => 'combo' }) ],
complete => sub {
if (!is_ip($smbserverip) && $smbserverip ne "") {
$in->ask_warn(N("Error"), N("IP address should be in format 1.2.3.4"));
return 1, 1;
}
if ($smbserver eq "" && $smbserverip eq "") {
$in->ask_warn(N("Error"), N("Either the server name or the server's IP must be given!"));
return 1, 0;
}
if ($smbshare eq "") {
$in->ask_warn(N("Error"), N("Samba share name missing!"));
return 1, 2;
}
if ($smbpassword ne "") {
local $::isWizard = 0;
my $yes = $in->ask_yesorno(
N("SECURITY WARNING!"),
N("You are about to set up printing to a Windows account with password. Due to a fault in the architecture of the Samba client software the password is put in clear text into the command line of the Samba client used to transmit the print job to the Windows server. So it is possible for every user on this machine to display the password on the screen by issuing commands as \"ps auxwww\".
We recommend to make use of one of the following alternatives (in all cases you have to make sure that only machines from your local network have access to your Windows server, for example by means of a firewall):
Use a password-less account on your Windows server, as the \"GUEST\" account or a special account dedicated for printing. Do not remove the password protection from a personal account or the administrator account.
Set up your Windows server to make the printer available under the LPD protocol. Then set up printing from this machine with the \"%s\" connection type in Printerdrake.
", N("Printer on remote lpd server")) .
($printer->{expert} ?
N("Set up your Windows server to make the printer available under the IPP protocol and set up printing from this machine with the \"%s\" connection type in Printerdrake.
", N("Enter a printer device URI")) : "") .
N("Connect your printer to a Linux server and let your Windows machine(s) connect to it as a client.
Do you really want to continue setting up this printer as you are doing now?"), 0);
return 0 if $yes;
return 1, 2;
}
return 0;
},
changed => sub {
return 0 if !$autodetect;
if ($oldmenuchoice ne $menuchoice) {
if ($menuentries->{$menuchoice} =~ m!^smb://([^/:]+)/([^/:]+)$!) {
$smbserver = $1;
$smbshare = $2;
}
$oldmenuchoice = $menuchoice;
}
return 0;
}
);
#- make the DeviceURI from, try to probe for available variable to
#- build a suitable URI.
$printer->{currentqueue}{connect} =
join '', ("smb://", ($smbuser && ($smbuser .
($smbpassword && ":$smbpassword") . '@')), ($workgroup && "$workgroup/"),
($smbserver || $smbserverip), "/$smbshare");
if (!$::testing && !files_exist('/usr/bin/smbclient')) {
$in->do_pkgs->install('samba-client') or do {
$in->ask_warn(N("Error"),
N("Could not install the %s packages!",
"Samba client") . " " .
N("Aborting"));
return 0;
};
}
$printer->{SPOOLER} eq 'cups' and printer::main::restart_queue($printer);
1;
}
sub setup_ncp {
my ($printer, $in, $upNetwork) = @_;
local $::isEmbedded = 0;
# Check whether the network functionality is configured and
# running
if (!check_network($printer, $in, $upNetwork, 0)) { return 0 };
# $in->set_help('setupNCP') if $::isInstall;
my ($uri, $ncpuser, $ncppassword, $ncpserver, $ncpqueue);
my $queue = $printer->{OLD_QUEUE};
if ($printer->{configured}{$queue} &&
$printer->{currentqueue}{connect} =~ m/^ncp:/) {
$uri = $printer->{currentqueue}{connect};
my $parameters = $uri =~ m!^\s*ncp://(.*)$!;
# Get the user's login and password from the URI
if ($parameters =~ m!([^@]*)@([^@]+)!) {
my $login = $1;
$parameters = $2;
if ($login =~ m!([^:]*):([^:]*)!) {
$ncpuser = $1;
$ncppassword = $2;
} else {
$ncpuser = $login;
$ncppassword = "";
}
} else {
$ncpuser = "";
$ncppassword = "";
}
# Get the workgroup, server, and share name
if ($parameters =~ m!([^/]+)/([^/]+)$!) {
$ncpserver = $1;
$ncpqueue = $2;
} else {
die qq(The "ncp://" URI must at least contain the server name and the share name!\n);
}
}
return 0 if !$in->ask_from(N("NetWare Printer Options"),
N("To print on a NetWare printer, you need to provide the NetWare print server name (Note! it may be different from its TCP/IP hostname!) as well as the print queue name for the printer you wish to access and any applicable user name and password."), [
{ label => N("Printer Server"), val => \$ncpserver },
{ label => N("Print Queue Name"), val => \$ncpqueue },
{ label => N("User name"), val => \$ncpuser },
{ label => N("Password"), val => \$ncppassword, hidden => 1 } ],
complete => sub {
unless ($ncpserver ne "") {
$in->ask_warn(N("Error"), N("NCP server name missing!"));
return 1, 0;
}
unless ($ncpqueue ne "") {
$in->ask_warn(N("Error"), N("NCP queue name missing!"));
return 1, 1;
}
return 0;
}
);
# Generate the Foomatic URI
$printer->{currentqueue}{connect} =
join '', ("ncp://", ($ncpuser && ($ncpuser .
($ncppassword && ":$ncppassword") . '@')),
"$ncpserver/$ncpqueue");
if (!$::testing && !files_exist('/usr/bin/nprint')) {
$in->do_pkgs->install('ncpfs') or do {
$in->ask_warn(N("Error"),
N("Could not install the %s packages!",
"ncpfs") . " " .
N("Aborting"));
return 0;
};
}
1;
}
sub setup_socket {
my ($printer, $in, $upNetwork) = @_;
local $::isEmbedded = 0;
# Check whether the network functionality is configured and
# running
if (!check_network($printer, $in, $upNetwork, 0)) { return 0 };
# $in->set_help('setupSocket') if $::isInstall;
my ($uri, $remotehost, $remoteport);
my $queue = $printer->{OLD_QUEUE};
if ($printer->{configured}{$queue} &&
$printer->{currentqueue}{connect} =~ m!^(socket:|ptal://?hpjd:)!) {
$uri = $printer->{currentqueue}{connect};
if ($uri =~ m!^ptal:!) {
if ($uri =~ m!^ptal://?hpjd:([^/:]+):([0-9]+)/?\s*$!) {
my $ptalport = $2 - 9100;
($remotehost, $remoteport) = ($1, $ptalport);
} elsif ($uri =~ m!^ptal://?hpjd:([^/:]+)\s*$!) {
($remotehost, $remoteport) = ($1, 9100);
}
} else {
($remotehost, $remoteport) =
$uri =~ m!^\s*socket://([^/:]+):([0-9]+)/?\s*$!;
}
} else {
$remotehost = "";
$remoteport = "9100";
}
my $autodetect = 0;
my @autodetected;
my $menuentries;
my @menuentrieslist;
my $menuchoice = "";
my $oldmenuchoice = "";
my $detectedprinterchosen = 0;
if ($printer->{AUTODETECT}) {
$autodetect = 1;
my $_w = $in->wait_message(N("Printer auto-detection"), N("Scanning network..."));
@autodetected = printer::detect::net_detect($printer->{TIMEOUT});
$printer->{AUTODETECTEDPRINTERSEXPERTSOCKET} = \@autodetected if @autodetected;
my ($host, $port);
foreach my $p (@autodetected) {
my $menustr;
if ($p->{port} =~ m!^socket://([^:]+):(\d+)$!) {
$host = $1;
$port = $2;
}
if ($p->{val}{DESCRIPTION}) {
$menustr = $p->{val}{DESCRIPTION};
$menustr .= N(", host \"%s\", port %s",
$host, $port);
} else {
$menustr = N("Host \"%s\", port %s", $host, $port);
}
$menuentries->{$menustr} = $p->{port};
if ($host eq $remotehost &&
$host eq $remotehost) {
$menuchoice = $menustr;
$detectedprinterchosen = 1;
}
}
@menuentrieslist = sort {
$menuentries->{$a} cmp $menuentries->{$b};
} keys(%$menuentries);
if ($printer->{configured}{$queue} &&
$printer->{currentqueue}{connect} =~ m!^(socket:|ptal://?hpjd:)! &&
$menuchoice eq "") {
my $menustr;
if ($printer->{currentqueue}{make}) {
$menustr = "$printer->{currentqueue}{make} $printer->{currentqueue}{model}";
$menustr .= N(", host \"%s\", port %s",
$remotehost, $remoteport);
} else {
$menustr = N("Host \"%s\", port %s",
$remotehost, $remoteport);
}
$menuentries->{$menustr} = "socket://$remotehost:$remoteport";
unshift(@menuentrieslist, $menustr);
$menuchoice = $menustr;
}
if ($#menuentrieslist < 0) {
$autodetect = 0;
} elsif ($menuchoice eq "") {
$menuchoice = $menuentrieslist[0];
if ($menuentries->{$menuentrieslist[0]} =~ m!^socket://([^:]+):(\d+)$!) {
$remotehost = $1;
$remoteport = $2;
$detectedprinterchosen = 1;
}
}
$oldmenuchoice = $menuchoice;
}
return 0 if !$in->ask_from_(
{
title => N("TCP/Socket Printer Options"),
messages => ($autodetect ?
N("Choose one of the auto-detected printers from the list or enter the hostname or IP and the optional port number (default is 9100) in the input fields.") :
N("To print to a TCP or socket printer, you need to provide the host name or IP of the printer and optionally the port number (default is 9100). On HP JetDirect servers the port number is usually 9100, on other servers it can vary. See the manual of your hardware.")),
callbacks => {
complete => sub {
unless ($remotehost ne "") {
$in->ask_warn(N("Error"), N("Printer host name or IP missing!"));
return 1, 0;
}
unless ($remoteport =~ /^[0-9]+$/) {
$in->ask_warn(N("Error"), N("The port number should be an integer!"));
return 1, 1;
}
return 0;
},
changed => sub {
return 0 if !$autodetect;
if ($oldmenuchoice ne $menuchoice) {
if ($menuentries->{$menuchoice} =~
m!^socket://([^:]+):(\d+)$!) {
$remotehost = $1;
$remoteport = $2;
$detectedprinterchosen = 1;
} else {
$detectedprinterchosen = 0;
}
$oldmenuchoice = $menuchoice;
} else {
$detectedprinterchosen = 0;
}
return 0;
}
}
},
[
{ label => ($autodetect ? "" : N("Printer host name or IP")),
val => \$remotehost },
{ label => ($autodetect ? "" : N("Port")), val => \$remoteport },
if_($autodetect,
{ val => \$menuchoice, list => \@menuentrieslist,
not_edit => 0, format => \&translate, sort => 0,
allow_empty_list => 1, type => 'list' })
]
);
#- make the Foomatic URI
$printer->{currentqueue}{connect} =
join '', ("socket://$remotehost", $remoteport ? ":$remoteport" : ());
#- LPD and LPRng need netcat ('nc') to access to socket printers
if (($printer->{SPOOLER} eq 'lpd' || $printer->{SPOOLER} eq 'lprng') &&
!$::testing && !files_exist('/usr/bin/nc')) {
$in->do_pkgs->install('nc') or do {
$in->ask_warn(N("Error"),
N("Could not install the %s packages!",
"nc") . " " .
N("Aborting"));
return 0;
}
}
# Auto-detect printer model
my $modelinfo;
if ($printer->{AUTODETECT}) {
$modelinfo = printer::detect::getSNMPModel($remotehost);
}
my $auto_hpoj;
if (defined($modelinfo) &&
$modelinfo->{MANUFACTURER} ne "" &&
$modelinfo->{MODEL} ne "") {
if (!$detectedprinterchosen) {
local $::isWizard = 0;
$in->ask_warn(N("Information"), N("Detected model: %s %s",
$modelinfo->{MANUFACTURER},
$modelinfo->{MODEL}));
}
$auto_hpoj = 1;
} else {
$auto_hpoj = 0;
}
# Do configuration of multi-function devices and look up model name
# in the printer database
setup_common($printer, $in,
"$modelinfo->{MANUFACTURER} $modelinfo->{MODEL}",
$printer->{currentqueue}{connect}, $auto_hpoj,
({port => $printer->{currentqueue}{connect},
val => $modelinfo }));
1;
}
sub setup_uri {
my ($printer, $in, $upNetwork) = @_;
local $::isEmbedded = 0;
# $in->set_help('setupURI') if $::isInstall;
if ($printer->{AUTODETECT} && $printer->{SPOOLER} eq 'cups') {
my $_w = $in->wait_message(N("Printerdrake"),
N("Refreshing Device URI list..."));
printer::services::restart("cups");
}
return if !$in->ask_from(N("Printer Device URI"),
N("You can specify directly the URI to access the printer. The URI must fulfill either the CUPS or the Foomatic specifications. Note that not all URI types are supported by all the spoolers."), [
{ label => N("Printer Device URI"),
val => \$printer->{currentqueue}{connect},
list => [ if_($printer->{currentqueue}{connect},
$printer->{currentqueue}{connect}),
($printer->{SPOOLER} eq 'cups' ?
printer::cups::lpinfo_v() :
("parallel:/",
"usb:/",
"serial:/",
"http://",
"ipp://",
"lpd://",
"smb://",
"ncp://",
"socket://",
"ptal:/mlc:",
"ptal:/hpjd:",
"hp:/usb/",
"hp:/par/",
"hp:/net/",
"file:/",
'postpipe:""')),
], not_edit => 0, sort => 0 }, ],
complete => sub {
unless ($printer->{currentqueue}{connect} =~ /[^:]+:.+/) {
$in->ask_warn(N("Error"), N("A valid URI must be entered!"));
return 1, 0;
}
return 0;
}
);
# Non-local printer, check network and abort if no network available
if ($printer->{currentqueue}{connect} !~ m!^(file:|parallel:|usb:|serial:|mtink:|ptal://?mlc|hp:/(usb|par))! &&
!check_network($printer, $in, $upNetwork, 0)) {
return 0;
# If the chosen protocol needs additional software, install it.
} elsif ($printer->{currentqueue}{connect} =~ /^lpd:/ &&
$printer->{SPOOLER} eq 'lpd' &&
!$::testing && !files_exist('/usr/bin/rlpr')) {
# LPD does not support filtered queues to a remote LPD server by itself
# It needs an additional program as "rlpr"
$in->do_pkgs->install('rlpr') or do {
$in->ask_warn(N("Error"),
N("Could not install the %s packages!",
"rlpr") . " " .
N("Aborting"));
return 0;
};
} elsif ($printer->{currentqueue}{connect} =~ /^smb:/ &&
!$::testing && !files_exist('/usr/bin/smbclient')) {
$in->do_pkgs->install('samba-client') or do {
$in->ask_warn(N("Error"),
N("Could not install the %s packages!",
"Samba client") . " " .
N("Aborting"));
return 0;
};
} elsif ($printer->{currentqueue}{connect} =~ /^ncp:/ &&
!$::testing && !files_exist('/usr/bin/nprint')) {
$in->do_pkgs->install('ncpfs') or do {
$in->ask_warn(N("Error"),
N("Could not install the %s packages!",
"ncpfs") . " " .
N("Aborting"));
return 0;
};
} elsif ($printer->{currentqueue}{connect} =~ /^socket:/ &&
#- LPD and LPRng need netcat ('nc') to access to socket printers
($printer->{SPOOLER} eq 'lpd' || $printer->{SPOOLER} eq 'lprng') &&
!$::testing && !files_exist('/usr/bin/nc')) {
$in->do_pkgs->install('nc') or do {
$in->ask_warn(N("Error"),
N("Could not install the %s packages!",
"nc") . " " .
N("Aborting"));
return 0;
};
}
if ($printer->{currentqueue}{connect} =~ m!^socket://([^:/]+)! ||
$printer->{currentqueue}{connect} =~ m!^lpd://([^:/]+)! ||
$printer->{currentqueue}{connect} =~ m!^http://([^:/]+)! ||
$printer->{currentqueue}{connect} =~ m!^ipp://([^:/]+)!) {
# Auto-detect printer model (works if host is an ethernet-connected
# printer)
my $remotehost = $1;
my $modelinfo = printer::detect::getSNMPModel($remotehost);
my $auto_hpoj;
if (defined($modelinfo) &&
$modelinfo->{MANUFACTURER} ne "" &&
$modelinfo->{MODEL} ne "") {
local $::isWizard = 0;
$in->ask_warn(N("Information"), N("Detected model: %s %s",
$modelinfo->{MANUFACTURER},
$modelinfo->{MODEL}));
$auto_hpoj = 1;
} else {
$auto_hpoj = 0;
}
# Do configuration of multi-function devices and look up model name
# in the printer database
setup_common($printer, $in,
"$modelinfo->{MANUFACTURER} $modelinfo->{MODEL}",
$printer->{currentqueue}{connect}, $auto_hpoj,
({port => $printer->{currentqueue}{connect},
val => $modelinfo }));
}
1;
}
sub setup_postpipe {
my ($printer, $in) = @_;
local $::isEmbedded = 0;
# $in->set_help('setupPostpipe') if $::isInstall;
my $uri;
my $commandline;
my $queue = $printer->{OLD_QUEUE};
if ($printer->{configured}{$queue} &&
$printer->{currentqueue}{connect} =~ m/^postpipe:/) {
$uri = $printer->{currentqueue}{connect};
$commandline = $1 if $uri =~ m!^\s*postpipe:"(.*)"$!;
} else {
$commandline = "";
}
return if !$in->ask_from(N("Pipe into command"),
N("Here you can specify any arbitrary command line into which the job should be piped instead of being sent directly to a printer."), [
{ label => N("Command line"),
val => \$commandline }, ],
complete => sub {
unless ($commandline ne "") {
$in->ask_warn(N("Error"), N("A command line must be entered!"));
return 1, 0;
}
return 0;
}
);
#- make the Foomatic URI
$printer->{currentqueue}{connect} = "postpipe:$commandline";
1;
}
sub setup_common {
my ($printer, $in, $makemodel, $device, $do_auto_detect, @autodetected) = @_;
local $::isEmbedded = 0;
#- Check whether the printer is an HP multi-function device and
#- configure HPOJ if it is one
my $hplipdevice = "";
my $ptaldevice = "";
my $isHPOJ = 0;
my $isHPLIP = 0;
my $w;
if ($device =~ m!^/dev/! || $device =~ m!^socket://!) {
# Ask user whether he has a multi-function device when he did not
# do auto-detection or when auto-detection failed
my $searchunknown = N("Unknown model");
if (!$do_auto_detect ||
$makemodel eq $searchunknown ||
$makemodel =~ /^\s*$/) {
local $::isWizard = 0;
if (!$printer->{noninteractive}) {
if (($device =~ m!/usb/!) &&
($printer->{SPOOLER} eq 'cups')) {
my $choice = $in->ask_from_list
(N("Add a new printer"),
N("On many HP printers there are special functions available, maintenance (ink level checking, nozzle cleaning. head alignment, ...) on all not too old inkjets, scanning on multi-function devices, and memory card access on printers with card readers. ") .
"\n\n" .
N("To access these extra functions on your HP printer, it must be set up with the appropriate software: ") .
N("Either with the newer HPLIP which allows printer maintenance through the easy-to-use graphical application \"Toolbox\" and four-edge full-bleed on newer PhotoSmart models ") .
N("or with the older HPOJ which allows only scanner and memory card access, but could help you in case of failure of HPLIP. ") .
"\n\n" .
N("What is your choice (choose \"None\" for non-HP printers)? "),
[N("None"), N("HPLIP"), N("HPOJ")], N("None"));
if ($choice eq N("HPLIP")) {
$isHPLIP = 1;
} elsif ($choice eq N("HPOJ")) {
$isHPOJ = 1;
}
} else {
$isHPOJ = $in->ask_yesorno(N("Add a new printer"),
N("Is your printer a multi-function device from HP or Sony (OfficeJet, PSC, LaserJet 1100/1200/1220/3000/3200/3300/4345 with scanner, DeskJet 450, Sony IJP-V100), an HP PhotoSmart or an HP LaserJet 2200?"), 0);
}
}
}
my $hplipentry;
if (($printer->{SPOOLER} eq 'cups') &&
(($hplipentry =
printer::main::hplip_device_entry($device, @autodetected)) ||
$isHPLIP)) {
# Device is supported by HPLIP
# Install HPLIP packages
my $hplipinstallfailed = 0;
if (!$::testing &&
!files_exist(qw(/usr/sbin/hpiod))) {
if ($::noX) {
$hplipinstallfailed = 1;
} else {
$w = $in->wait_message(N("Printerdrake"),
N("Installing %s package...",N("HPLIP")))
if !$printer->{noninteractive};
$in->do_pkgs->install('hplip')
or do {
$in->ask_warn(N("Warning"),
N("Could not install the %s packages!",
N("HPLIP")) . " " .
N("Only printing will be possible on the %s.",
$makemodel));
$hplipinstallfailed = 1;
};
}
}
# Remove old HPOJ configuration for this device
if (-f "/usr/sbin/ptal-mlcd") { # HPOJ installed?
if (my $configfile =
printer::main::remove_hpoj_config($device, @autodetected)) {
if (!$printer->{noninteractive} && !$::noX) {
undef $w;
local $::isWizard = 0;
$in->ask_warn
(N("Error"),
N("Could not remove your old HPOJ configuration file %s for your %s! ",
$configfile, $makemodel) .
N("Please remove the file manually and restart HPOJ."));
}
}
}
# Start HPLIP and get device URI
undef $w;
$w = $in->wait_message(
N("Printerdrake"),
N("Checking device and configuring %s...",N("HPLIP")))
if !$printer->{noninteractive};
if (!$hplipinstallfailed) {
if ($isHPLIP) {
my @uris = printer::main::start_hplip_manual();
my @menu; my %menuhash;
for my $item (@uris) {
if ($item =~ m!^hp:/(usb|par|net)/(\S*?)(\?\S*|)$!){
my $modelname = "HP " . $2;
$modelname =~ s/_/ /g;
push(@menu, $modelname);
$menuhash{$modelname} = $item;
}
}
undef $w;
local $::isWizard = 0;
my $choice = $in->ask_from_list
(N("Add a new printer"),
N("Which printer do you want to set up with HPLIP?"),
\@menu, $menu[0]);
$hplipdevice = $menuhash{$choice};
$hplipentry =
printer::main::hplip_device_entry_from_uri
($hplipdevice);
$makemodel = $choice;
} else {
$hplipdevice = printer::main::start_hplip
($device, $hplipentry, @autodetected);
}
}
if ($hplipdevice) {
# Configure scanning with SANE on HP's MF devices
if ($hplipentry->{scan}) {
# Install SANE
if (!$::testing &&
(!files_exist(qw(/usr/bin/scanimage
/usr/bin/xscanimage
/etc/sane.d/dll.conf
/usr/lib/libsane-hpaio.so.1)) ||
(!files_exist(qw(/usr/bin/xsane)) &&
!files_exist(qw(/usr/bin/kooka)) &&
($::isInstall ||
!$in->do_pkgs->is_installed('scanner-gui'))))) {
undef $w;
$w = $in->wait_message(
N("Printerdrake"),
N("Installing SANE packages..."))
if !$printer->{noninteractive};
$::noX
or $in->do_pkgs->install('sane-backends',
'sane-frontends',
($::isInstall ?
'xsane' :
'scanner-gui'),
'libsane-hpaio1')
or do {
$in->ask_warn(N("Warning"),
N("Could not install the %s packages!",
"SANE") . " " .
N("Scanning on the %s will not be possible.",
$makemodel));
};
}
# Configure the HPLIP SANE backend
printer::main::config_sane('hpaio');
}
if (!$printer->{noninteractive} && !$::noX) {
my $text = "";
# Inform user about how to use HPLIP extra functions
$text = hplip_help($makemodel, $hplipdevice);
if ($text) {
undef $w;
local $::isWizard = 0;
$in->ask_warn
(N("Using and Maintaining your %s",
$makemodel),
$text);
}
}
# Take the DeviceURI from $hplipdevice.
$printer->{currentqueue}{connect} = $hplipdevice;
}
}
if (!$hplipdevice) {
if ($makemodel =~ /HP\s+(OfficeJet|PSC|PhotoSmart|LaserJet\s+(1200|1220|2200|30(15|20|30)|3200|33.0|4345)|(DeskJet|dj)\s*450)/i ||
$makemodel =~ /Sony\s+IJP[\s\-]+V[\s\-]+100/i ||
$isHPOJ) {
# Install HPOJ package
my $hpojinstallfailed = 0;
if (!$::testing &&
!files_exist(qw(/usr/sbin/ptal-mlcd
/usr/sbin/ptal-init
/usr/bin/xojpanel
/usr/sbin/lsusb))) {
if ($::noX) {
$hpojinstallfailed = 1;
} else {
$w = $in->wait_message(N("Printerdrake"),
N("Installing %s package...",N("HPOJ")))
if !$printer->{noninteractive};
$in->do_pkgs->install('hpoj', 'xojpanel', 'usbutils')
or do {
$in->ask_warn(N("Warning"),
N("Could not install the %s packages!",
N("HPOJ")) . " " .
N("Only printing will be possible on the %s.",
$makemodel));
$hpojinstallfailed = 1;
};
}
}
# Configure and start HPOJ
undef $w;
$w = $in->wait_message
(N("Printerdrake"),
N("Checking device and configuring %s...",N("HPOJ")))
if !$printer->{noninteractive};
eval { $ptaldevice = printer::main::configure_hpoj
($device, @autodetected) if !$hpojinstallfailed };
if (my $err = $@) {
warn qq(HPOJ conf failure: "$err");
log::l(qq(HPOJ conf failure: "$err"));
}
if ($ptaldevice) {
# HPOJ has determined the device name, make use of
# it if we did not know it before
if (!$do_auto_detect ||
!$makemodel ||
$makemodel eq $searchunknown ||
$makemodel =~ /^\s*$/) {
$makemodel = $ptaldevice;
$makemodel =~ s/^.*:([^:]+)$/$1/;
$makemodel =~ s/_/ /g;
if ($makemodel =~ /^\s*IJP/i) {
$makemodel = "Sony $makemodel";
} else {
$makemodel = "HP $makemodel";
}
}
# Configure scanning with SANE on the MF device
if ($makemodel !~ /HP\s+PhotoSmart/i &&
$makemodel !~ /HP\s+LaserJet\s+2200/i &&
$makemodel !~ /HP\s+(DeskJet|dj)\s*450/i) {
# Install SANE
if (!$::testing &&
(!files_exist(qw(/usr/bin/scanimage
/usr/bin/xscanimage
/etc/sane.d/dll.conf
/usr/lib/libsane-hpoj.so.1)) ||
(!files_exist(qw(/usr/bin/xsane)) &&
!files_exist(qw(/usr/bin/kooka)) &&
($::isInstall ||
!$in->do_pkgs->is_installed('scanner-gui'))))) {
undef $w;
$w = $in->wait_message
(N("Printerdrake"),
N("Installing SANE packages..."))
if !$printer->{noninteractive};
$::noX
or $in->do_pkgs->install('sane-backends',
'sane-frontends',
($::isInstall ?
'xsane' :
'scanner-gui'),
'libsane-hpoj1')
or do {
$in->ask_warn(N("Warning"),
N("Could not install the %s packages!",
"SANE") . " " .
N("Scanning on the %s will not be possible.",
$makemodel));
};
}
# Configure the HPOJ SANE backend
printer::main::config_sane('hpoj');
}
# Configure photo card access with mtools and MToolsFM
if (($makemodel =~ /HP\s+PhotoSmart/i ||
$makemodel =~ /HP\s+PSC\s*9[05]0/i ||
$makemodel =~ /HP\s+PSC\s*13[15]\d/i ||
$makemodel =~ /HP\s+PSC\s*161\d/i ||
$makemodel =~ /HP\s+PSC\s*2\d\d\d/i ||
$makemodel =~ /HP\s+OfficeJet\s+D\s*1[45]5/i ||
$makemodel =~ /HP\s+OfficeJet\s+71[34]0/i ||
$makemodel =~ /HP\s+OfficeJet\s+91\d\d/i ||
$makemodel =~ /HP\s+(DeskJet|dj)\s*450/i) &&
$makemodel !~ /HP\s+PhotoSmart\s+7150/i) {
# Install mtools and MToolsFM
if (!$::testing &&
!files_exist(qw(/usr/bin/mdir
/usr/bin/mcopy
/usr/bin/MToolsFM
))) {
undef $w;
$w = $in->wait_message
(N("Printerdrake"),
N("Installing mtools packages..."))
if !$printer->{noninteractive};
$::noX
or $in->do_pkgs->install('mtools', 'mtoolsfm')
or do {
$in->ask_warn(N("Warning"),
N("Could not install the %s packages!",
"Mtools") . " " .
N("Photo memory card access on the %s will not be possible.",
$makemodel));
};
}
# Configure mtools/MToolsFM for photo card access
printer::main::config_photocard();
}
if (!$printer->{noninteractive} && !$::noX) {
my $text = "";
# Inform user about how to scan with his MF device
$text = scanner_help($makemodel, "ptal://$ptaldevice");
if ($text) {
undef $w;
local $::isWizard = 0;
$in->ask_warn
(N("Scanning on your HP multi-function device"),
$text);
}
# Inform user about how to access photo cards with his
# MF device
$text = photocard_help($makemodel, "ptal://$ptaldevice");
if ($text) {
undef $w;
local $::isWizard = 0;
$in->ask_warn(N("Photo memory card access on your HP multi-function device"),
$text);
}
}
# make the DeviceURI from $ptaldevice.
$printer->{currentqueue}{connect} =
"ptal://" . $ptaldevice;
} else {
# make the DeviceURI from $device.
$printer->{currentqueue}{connect} = $device;
}
} else {
# make the DeviceURI from $device.
$printer->{currentqueue}{connect} = $device;
}
$w = $in->wait_message(
N("Printerdrake"),
N("Configuring device..."))
if !$printer->{noninteractive} && !defined($w);
}
} else {
# make the DeviceURI from $device.
$printer->{currentqueue}{connect} = $device;
}
if ($printer->{currentqueue}{connect} !~ /:/) {
if ($printer->{currentqueue}{connect} =~ /usb/) {
$printer->{currentqueue}{connect} =
"usb:" . $printer->{currentqueue}{connect};
} elsif ($printer->{currentqueue}{connect} =~ /(serial|tty)/) {
$printer->{currentqueue}{connect} =
"serial:" . $printer->{currentqueue}{connect};
} elsif ($printer->{currentqueue}{connect} =~
/(printers|parallel|parport|lp\d)/) {
$printer->{currentqueue}{connect} =
"parallel:" . $printer->{currentqueue}{connect};
} else {
$printer->{currentqueue}{connect} =
"file:" . $printer->{currentqueue}{connect};
}
}
#- if CUPS is the spooler, make sure that CUPS knows the device
if ($printer->{SPOOLER} eq "cups" &&
$device !~ /^lpd:/ &&
$device !~ /^smb:/ &&
$device !~ /^socket:/ &&
$device !~ /^http:/ &&
$device !~ /^ipp:/) {
my $_w = $in->wait_message(
N("Printerdrake"),
N("Making printer port available for CUPS..."))
if !$printer->{noninteractive};
printer::main::assure_device_is_available_for_cups($ptaldevice ||
$device);
}
#- Read the printer driver database if necessary
if (keys %printer::main::thedb == 0) {
my $_w = $in->wait_message(
N("Printerdrake"), N("Reading printer database..."))
if !$printer->{noninteractive};
printer::main::read_printer_db($printer, $printer->{SPOOLER});
}
#- Search the database entry which matches the detected printer best
my $descr = "";
foreach (@autodetected) {
$device eq $_->{port} or next;
my ($automake, $automodel, $autodescr, $autocmdset, $autosku) =
($_->{val}{MANUFACTURER}, $_->{val}{MODEL},
$_->{val}{DESCRIPTION}, $_->{val}{'COMMAND SET'},
$_->{val}{SKU});
# Clean some manufacturer's names
my $descrmake = printer::main::clean_manufacturer_name($automake);
if ($automake && $autosku) {
$descr = "$descrmake|$autosku";
} elsif ($automake && $automodel) {
$descr = "$descrmake|$automodel";
} elsif ($autodescr) {
$descr = $autodescr;
$descr =~ s/ /|/;
} elsif ($automodel) {
$descr = $automodel;
$descr =~ s/ /|/;
} elsif ($automake) {
$descr = "$descrmake|";
}
# Remove manufacturer's name from the beginning of the
# description (do not do this with manufacturer names which
# contain odd characters)
$descr =~ s/^$descrmake\|\s*$descrmake\s*/$descrmake|/i
if $descrmake &&
$descrmake !~ m![\\/\(\)\[\]\|\.\$\@\%\*\?]!;
# Clean up the description from noise which makes the best match
# difficult
$descr =~ s/\s+[Ss]eries//i;
$descr =~ s/\s+\(?[Pp]rinter\)?$//i;
$printer->{DBENTRY} = "";
# Try to find an exact match, check both whether the detected
# make|model is in the make|model of the database entry and vice versa
# If there is more than one matching database entry, the longest match
# counts.
my $matchlength = -100;
foreach my $entry (keys %printer::main::thedb) {
# Try to match the device ID string of the auto-detection
if ($printer::main::thedb{$entry}{make} =~ /Generic/i) {
# Database entry for generic printer, check printer
# languages (command set)
my $_cmd = $printer::main::thedb{$entry}{devidcmd};
if ($printer::main::thedb{$entry}{model} =~
m!PCL\s*5/5e!i) {
# Generic PCL 5/5e Printer
if ($autocmdset =~
/(^|[:,])PCL\s*\-*\s*(5|)([,;]|$)/i) {
if ($matchlength < -50) {
$matchlength = -50;
$printer->{DBENTRY} = $entry;
next;
}
}
} elsif ($printer::main::thedb{$entry}{model} =~
m!PCL\s*(6|XL)!i) {
# Generic PCL 6/XL Printer
if ($autocmdset =~
/(^|[:,])PCL\s*\-*\s*(6|XL)([,;]|$)/i) {
if ($matchlength < -40) {
$matchlength = -40;
$printer->{DBENTRY} = $entry;
next;
}
}
} elsif ($printer::main::thedb{$entry}{model} =~
m!(PostScript)!i) {
# Generic PostScript Printer
if ($autocmdset =~
/(^|[:,])(PS|POSTSCRIPT)[^:;,]*([,;]|$)/i) {
if ($matchlength < -10) {
$matchlength = -10;
$printer->{DBENTRY} = $entry;
next;
}
}
}
} else {
# "Real" manufacturer, check manufacturer, model, and/or
# description
my $matched = 1;
my ($mfg, $mdl, $des);
if ($mfg = $printer::main::thedb{$entry}{devidmake}) {
$mfg =~ s/Hewlett[-\s_]Packard/HP/i;
if (uc($mfg) ne uc($automake)) {
$matched = 0;
}
}
if ($mdl = $printer::main::thedb{$entry}{devidmodel}) {
if ($mdl ne $automodel) {
$matched = 0;
}
}
if ($des = $printer::main::thedb{$entry}{deviddesc}) {
$des =~ s/Hewlett[-\s_]Packard/HP/;
$des =~ s/HEWLETT[-\s_]PACKARD/HP/;
if ($des ne $autodescr) {
$matched = 0;
}
}
if ($matched && ($des || $mfg && $mdl)) {
# Full match to known auto-detection data
$printer->{DBENTRY} = $entry;
$matchlength = 1000;
last;
}
}
# Do not search human-readable make and model names if we had an
# exact match or a match to the auto-detection ID string
next if $matchlength >= 100;
# Try to match the (human-readable) make and model of the
# Foomatic database or of thr PPD file
my $dbmakemodel;
if ($printer->{expert}) {
$dbmakemodel = $1 if $entry =~ m/^(.*)\|[^\|]*$/;
} else {
$dbmakemodel = $entry;
}
# Do not try to match if the database entry does not provide
# make and model
next unless $dbmakemodel;
# If make and model match exactly, we have found the correct
# entry and we can stop searching human-readable makes and
# models
if (lc($dbmakemodel) eq lc($descr)) {
$printer->{DBENTRY} = $entry;
$matchlength = 100;
next;
}
# Matching a part of the human-readable makes and models
# should only be done if the search term is not the name of
# an old model, otherwise the newest, not yet listed models
# match with the oldest model of the manufacturer (as the
# Epson Stylus Photo 900 with the original Epson Stylus Photo)
my @badsearchterms =
("HP|DeskJet",
"HP|LaserJet",
"HP|DesignJet",
"HP|OfficeJet",
"HP|PhotoSmart",
"EPSON|Stylus",
"EPSON|Stylus Color",
"EPSON|Stylus Photo",
"EPSON|Stylus Pro",
"XEROX|WorkCentre",
"XEROX|DocuPrint");
if (!member($descr, @badsearchterms)) {
my $searchterm = $descr;
my $lsearchterm = length($searchterm);
$searchterm =~ s!([\\/\(\)\[\]\|\.\$\@\%\*\?])!\\$1!g;
if ($lsearchterm > $matchlength &&
$dbmakemodel =~ m!$searchterm!i) {
$matchlength = $lsearchterm;
$printer->{DBENTRY} = $entry;
}
}
if (!member($dbmakemodel, @badsearchterms)) {
my $searchterm = $dbmakemodel;
my $lsearchterm = length($searchterm);
$searchterm =~ s!([\\/\(\)\[\]\|\.\$\@\%\*\?])!\\$1!g;
if ($lsearchterm > $matchlength &&
$descr =~ m!$searchterm!i) {
$matchlength = $lsearchterm;
$printer->{DBENTRY} = $entry;
}
}
}
# No matching printer found, try a best match as last mean (not
# when generating queues non-interactively)
if (!$printer->{noninteractive}) {
$printer->{DBENTRY} ||=
bestMatchSentence($descr, keys %printer::main::thedb);
# If the manufacturer was not guessed correctly, discard the
# guess.
my $guessedmake = lc($1) if $printer->{DBENTRY} =~ /^([^\|]+)\|/;
if ($guessedmake !~ /Generic/i &&
$descr !~ /$guessedmake/i &&
($guessedmake ne "hp" ||
$descr !~ /Hewlett[\s-]+Packard/i))
{ $printer->{DBENTRY} = "" };
}
}
#- Pre-fill the "Description" field with the printer's model name
if (!$printer->{currentqueue}{desc} && $descr) {
$printer->{currentqueue}{desc} = $descr;
$printer->{currentqueue}{desc} =~ s/\|/ /g;
}
#- When we have chosen a printer here, the question whether the
#- automatically chosen model from the database is correct, should
#- have "This model is correct" as default answer
delete($printer->{MANUALMODEL});
1;
}
sub choose_printer_name {
my ($printer, $in) = @_;
local $::isEmbedded = 0;
# Name, description, location
# $in->set_help('setupPrinterName') if $::isInstall;
my $default = $printer->{currentqueue}{queue};
$in->ask_from_(
{ title => N("Enter Printer Name and Comments"),
#cancel => !$printer->{configured}{$queue} ? '' : N("Remove queue"),
callbacks => { complete => sub {
unless ($printer->{currentqueue}{queue} =~ /^[A-Za-z0-9_]+$/) {
$in->ask_warn(N("Error"), N("Name of printer should contain only letters, numbers and the underscore"));
return 1, 0;
}
local $::isWizard = 0;
if ($printer->{configured}{$printer->{currentqueue}{queue}}
&& $printer->{currentqueue}{queue} ne $default &&
!$in->ask_yesorno(N("Warning"), N("The printer \"%s\" already exists,\ndo you really want to overwrite its configuration?",
$printer->{currentqueue}{queue}),
0)) {
return 1, 0; # Let the user correct the name
}
my $ml = 12;
if ((length($printer->{currentqueue}{queue}) > $ml) &&
!$in->ask_yesorno(N("Warning"), N("The printer name \"%s\" has more than 12 characters which can make the printer unaccessible from Windows clients. Do you really want to use this name?",
$printer->{currentqueue}{queue}),
0)) {
return 1, 0; # Let the user correct the name
}
return 0;
},
},
messages =>
N("Every printer needs a name (for example \"printer\"). The Description and Location fields do not need to be filled in. They are comments for the users.") },
[ { label => N("Name of printer"), val => \$printer->{currentqueue}{queue} },
{ label => N("Description"), val => \$printer->{currentqueue}{desc} },
{ label => N("Location"), val => \$printer->{currentqueue}{loc} },
]) or return 0;
$printer->{QUEUE} = $printer->{currentqueue}{queue};
1;
}
sub get_db_entry {
my ($printer, $in) = @_;
local $::isEmbedded = 0;
#- Read the printer driver database if necessary
if (keys %printer::main::thedb == 0) {
my $_w = $in->wait_message(N("Printerdrake"),
N("Reading printer database..."))
if $printer->{noninteractive};
printer::main::read_printer_db($printer, $printer->{SPOOLER});
}
my $_w = $in->wait_message(N("Printerdrake"),
N("Preparing printer database..."))
if !$printer->{noninteractive};
my $queue = $printer->{OLD_QUEUE};
if ($printer->{configured}{$queue}) {
# The queue was already configured
if ($printer->{configured}{$queue}{queuedata}{foomatic}) {
# The queue was configured with Foomatic
my $driverstr;
if ($printer->{configured}{$queue}{queuedata}{driver} eq "Postscript") {
$driverstr = "PostScript";
} else {
$driverstr = "GhostScript + $printer->{configured}{$queue}{queuedata}{driver}";
}
my $make = uc($printer->{configured}{$queue}{queuedata}{make});
my $model = $printer->{configured}{$queue}{queuedata}{model};
if ($printer->{expert}) {
$printer->{DBENTRY} = "$make|$model|$driverstr";
# database key contains the "(recommended)" for the
# recommended driver, so add it if necessary
unless (exists($printer::main::thedb{$printer->{DBENTRY}})) {
$printer->{DBENTRY} .= " $precstr";
}
} else {
$printer->{DBENTRY} = "$make|$model";
}
$printer->{OLD_CHOICE} = $printer->{DBENTRY};
} elsif ($printer->{configured}{$queue}{queuedata}{ppd}) {
# Do we have a native CUPS driver or a PostScript PPD file?
$printer->{DBENTRY} =
printer::main::get_descr_from_ppd($printer) ||
$printer->{DBENTRY};
unless (exists($printer::main::thedb{$printer->{DBENTRY}})) {
$printer->{DBENTRY} .= " $precstr";
}
$printer->{OLD_CHOICE} = $printer->{DBENTRY};
}
my ($make, $model);
if ($printer->{DBENTRY} eq "") {
# Point the list cursor at least to manufacturer and model of
# the printer
$printer->{DBENTRY} = "";
if ($printer->{configured}{$queue}{queuedata}{foomatic}) {
$make = uc($printer->{configured}{$queue}{queuedata}{make});
$model = $printer->{configured}{$queue}{queuedata}{model};
} elsif ($printer->{configured}{$queue}{queuedata}{ppd}) {
my $makemodel =
printer::main::get_descr_from_ppd($printer);
if ($makemodel =~ m!^([^\|]+)\|([^\|]+)(|\|.*)$!) {
$make = $1;
$model = $2;
}
}
foreach my $key (keys %printer::main::thedb) {
if ($printer->{expert} &&
$key =~ /^$make\|$model\|.*$sprecstr.*$/ ||
!$printer->{expert} && $key =~ /^$make\|$model$/) {
$printer->{DBENTRY} = $key;
}
}
}
if ($printer->{DBENTRY} eq "") {
# Exact match of make and model did not work, try to clean
# up the model name
$model =~ s/PS//;
$model =~ s/PostScript//i;
$model =~ s/Series//i;
foreach my $key (keys %printer::main::thedb) {
if ($printer->{expert} && $key =~ /^$make\|$model\|.*$sprecstr.*$/ ||
!$printer->{expert} && $key =~ /^$make\|$model$/) {
$printer->{DBENTRY} = $key;
}
}
}
if ($printer->{DBENTRY} eq "" && $make ne "") {
# Exact match with cleaned-up model did not work, try a best match
my $matchstr = "$make|$model";
$printer->{DBENTRY} =
bestMatchSentence($matchstr, keys %printer::main::thedb);
# If the manufacturer was not guessed correctly, discard the
# guess.
my $guessedmake = lc($1) if $printer->{DBENTRY} =~ /^([^\|]+)\|/;
if ($matchstr !~ /$guessedmake/i &&
($guessedmake ne "hp" ||
$matchstr !~ /Hewlett[\s-]+Packard/i))
{ $printer->{DBENTRY} = "" };
}
if ($printer->{DBENTRY} eq "") {
# Set the OLD_CHOICE to a non-existing value
$printer->{OLD_CHOICE} = "XXX";
}
} else {
if ($printer->{expert} && $printer->{DBENTRY} !~ /$sprecstr/) {
my ($make, $model) = $printer->{DBENTRY} =~ /^([^\|]+)\|([^\|]+)\|/;
foreach my $key (keys %printer::main::thedb) {
if ($key =~ /^$make\|$model\|.*$sprecstr.*$/) {
$printer->{DBENTRY} = $key;
}
}
}
$printer->{OLD_CHOICE} = $printer->{DBENTRY};
}
1;
}
sub is_model_correct {
my ($printer, $in) = @_;
local $::isEmbedded = 0;
# $in->set_help('chooseModel') if $::isInstall;
my $dbentry = $printer->{DBENTRY};
if (!$dbentry) {
# If printerdrake could not determine the model, omit this dialog and
# let the user choose manually.
$printer->{MANUALMODEL} = 1;
return 1;
}
$dbentry =~ s/\|/ /g;
my $res = $in->ask_from_list_(
N("Your printer model"),
N("Printerdrake has compared the model name resulting from the printer auto-detection with the models listed in its printer database to find the best match. This choice can be wrong, especially when your printer is not listed at all in the database. So check whether the choice is correct and click \"The model is correct\" if so and if not, click \"Select model manually\" so that you can choose your printer model manually on the next screen.
For your printer Printerdrake has found:
%s", $dbentry),
[N("The model is correct"),
N("Select model manually")],
($printer->{MANUALMODEL} ? N("Select model manually") :
N("The model is correct")));
return 0 if !$res;
$printer->{MANUALMODEL} = $res eq N("Select model manually");
1;
}
sub choose_model {
my ($printer, $in) = @_;
local $::isEmbedded = 0;
# $in->set_help('chooseModel') if $::isInstall;
#- Read the printer driver database if necessary
if (keys %printer::main::thedb == 0) {
my $_w = $in->wait_message(N("Printerdrake"),
N("Reading printer database..."));
printer::main::read_printer_db($printer, $printer->{SPOOLER});
}
unless (exists($printer::main::thedb{$printer->{DBENTRY}})) {
$printer->{DBENTRY} = N("Raw printer (No driver)");
}
# Choose the printer/driver from the list
my $choice = $printer->{DBENTRY};
my $loadppdchosen = 0;
while (1) {
if ($in->ask_from_({
title => N("Printer model selection"),
messages => N("Which printer model do you have?") .
N("
Please check whether Printerdrake did the auto-detection of your printer model correctly. Find the correct model in the list when a wrong model or \"Raw printer\" is highlighted.")
. " " .
N("If your printer is not listed, choose a compatible (see printer manual) or a similar one."),
#cancel => (""),
#ok => (""),
}, [
# List the printers/drivers
{ val => \$choice, format => \&translate,
sort => 1, separator => "|", tree_expanded => 0,
quit_if_double_click => 1, allow_empty_list => 1,
list => [ keys %printer::main::thedb ] },
# Button to install a manufacturer-supplied PPD file
{ clicked_may_quit =>
sub {
$loadppdchosen = 1;
1;
},
val => N("Install a manufacturer-supplied PPD file") },
])) {
$printer->{DBENTRY} = $choice if !$loadppdchosen;
} else {
return 0;
}
last if !$loadppdchosen;
# Install a manufacturer-supplied PPD file
my $ppdentry;
if ($ppdentry = installppd($printer, $in)) {
$choice = $ppdentry;
}
$loadppdchosen = 0;
}
return 1;
}
sub installppd {
my ($printer, $in) = @_;
local $::isEmbedded = 0;
# Install a manufacturer-supplied PPD file
# The dialogs to choose the PPD file should appear as extra
# windows and not embedded in the "Add printer" wizard.
local $::isWizard = 0;
my $ppdfile;
my ($mediachoice);
while (1) {
# Tell user about PPD file installation
$in->ask_from('Printerdrake',
N("Every PostScript printer is delivered with a PPD file which describes the printer's options and features.") . " " .
N("This file is usually somewhere on the CD with the Windows and Mac drivers delivered with the printer.") . " " .
N("You can find the PPD files also on the manufacturer's web sites.") . " " .
N("If you have Windows installed on your machine, you can find the PPD file on your Windows partition, too.") . "\n" .
N("Installing the printer's PPD file and using it when setting up the printer makes all options of the printer available which are provided by the printer's hardware") . "\n" .
N("Here you can choose the PPD file to be installed on your machine, it will then be used for the setup of your printer."),
[
{ label => N("Install PPD file from"),
val => \$mediachoice,
list => [N("CD-ROM"),
N("Floppy Disk"),
N("Other place")],
not_edit => 1, sort => 0 },
],
) or return 0;
my $dir;
if ($mediachoice eq N("CD-ROM")) {
$dir = "/mnt/cdrom";
} elsif ($mediachoice eq N("Floppy Disk")) {
$dir = "/mnt/floppy";
} elsif ($mediachoice eq N("Other place")) {
$dir = "/mnt";
} else {
return 0;
}
# Let user select a PPD file from a floppy, hard disk, ...
$ppdfile = $in->ask_file(N("Select PPD file"), $dir);
last if !$ppdfile;
if (! -r $ppdfile) {
$in->ask_warn(N("Error"),
N("The PPD file %s does not exist or is unreadable!",
$ppdfile));
next;
}
if (! printer::main::checkppd($printer, $ppdfile)) {
$in->ask_warn(N("Error"),
N("The PPD file %s does not conform with the PPD specifications!",
$ppdfile));
next;
}
last;
}
return 0 if !$ppdfile;
# Install the PPD file in /usr/share/cups/ppd/printerdrake/
my $w = $in->wait_message(N("Printerdrake"),
N("Installing PPD file..."));
my $ppdentry = printer::main::installppd($printer, $ppdfile);
undef $w;
return $ppdentry;
}
my %lexmarkinkjet_options = (
'parallel:/dev/lp0' => " -o Port=ParPort1",
'parallel:/dev/lp1' => " -o Port=ParPort2",
'parallel:/dev/lp2' => " -o Port=ParPort3",
'usb:/dev/usb/lp0' => " -o Port=USB1",
'usb:/dev/usb/lp1' => " -o Port=USB2",
'usb:/dev/usb/lp2' => " -o Port=USB3",
'file:/dev/lp0' => " -o Port=ParPort1",
'file:/dev/lp1' => " -o Port=ParPort2",
'file:/dev/lp2' => " -o Port=ParPort3",
'file:/dev/usb/lp0' => " -o Port=USB1",
'file:/dev/usb/lp1' => " -o Port=USB2",
'file:/dev/usb/lp2' => " -o Port=USB3",
);
my %drv_x125_options = (
'usb:/dev/usb/lp0' => " -o Device=usb_lp1",
'usb:/dev/usb/lp1' => " -o Device=usb_lp2",
'usb:/dev/usb/lp2' => " -o Device=usb_lp3",
'usb:/dev/usb/lp3' => " -o Device=usb_lp3",
'file:/dev/usb/lp0' => " -o Device=usb_lp1",
'file:/dev/usb/lp1' => " -o Device=usb_lp2",
'file:/dev/usb/lp2' => " -o Device=usb_lp3",
'file:/dev/usb/lp3' => " -o Device=usb_lp3",
);
sub get_printer_info {
my ($printer, $in) = @_;
local $::isEmbedded = 0;
my $queue = $printer->{OLD_QUEUE};
my $oldchoice = $printer->{OLD_CHOICE};
my $newdriver = 0;
if (!$printer->{configured}{$queue} || # New queue or
($oldchoice && $printer->{DBENTRY} && # make/model/driver changed
($oldchoice ne $printer->{DBENTRY} ||
$printer->{currentqueue}{driver} ne
$printer::main::thedb{$printer->{DBENTRY}}{driver}))) {
delete($printer->{currentqueue}{printer});
delete($printer->{currentqueue}{ppd});
$printer->{currentqueue}{foomatic} = 0;
# Read info from printer database
foreach (qw(printer ppd driver make model)) { #- copy some parameter, shorter that way...
$printer->{currentqueue}{$_} = $printer::main::thedb{$printer->{DBENTRY}}{$_};
}
$newdriver = 1;
}
# Use the "printer" and not the "foomatic" field to identify a Foomatic
# queue because in a new queue "foomatic" is not set yet.
if ($printer->{currentqueue}{printer} || # We have a Foomatic queue
$printer->{currentqueue}{ppd}) { # We have a PPD queue
if ($printer->{currentqueue}{printer}) { # Foomatic queue?
# In case of a new queue "foomatic" was not set yet
$printer->{currentqueue}{foomatic} = 1;
$printer->{currentqueue}{ppd} = undef;
} elsif ($printer->{currentqueue}{ppd}) { # PPD queue?
# If we had a Foomatic queue before, unmark the flag and
# initialize the "printer" and "driver" fields
$printer->{currentqueue}{foomatic} = 0;
$printer->{currentqueue}{printer} = undef;
$printer->{currentqueue}{driver} = "PPD";
}
# Now get the options for this printer/driver combo
if ($printer->{configured}{$queue} &&