On Thu, 2019-02-14 at 13:52 +0000, Colin Watson wrote:
> On Wed, Feb 13, 2019 at 10:51:17PM -0700, Kevin Locke wrote:
>> The problem is that the ellipsized choice text can't be mapped back
>> to the choice value.  I have attached a patch which adds this
>> mapping.
> 
> Oh dear.  Thanks - but doesn't Debconf::Element::Dialog::Select have
> an analogous problem?

Yes indeed.  Good catch.  Here's an updated patch which fixes both.

Cheers,
Kevin
>From ff3b7c6fe834aeeb978aeabf82ac638f2e5374e4 Mon Sep 17 00:00:00 2001
Message-Id: <ff3b7c6fe834aeeb978aeabf82ac638f2e5374e4.1550162500.git.ke...@kevinlocke.name>
From: Kevin Locke <ke...@kevinlocke.name>
Date: Wed, 13 Feb 2019 22:17:07 -0700
Subject: [PATCH] Dialog: Fix whiptail ellipsized selections

When displaying a select or multiselect using the dialog frontend with
whiptail, if any choices are changed by the ellipsize method (i.e. any
choices are longer than the available screen width to display choices)
they can not be selected.  Running with DEBCONF_DEBUG=developer prints
the message:

    debconf (developer): Input value, "%s" not found in C choices! This should never happen. Perhaps the templates were incorrectly localized.

The cause is that translate_to_C is unable to map the ellipsized choice
text back to the choice value.  This commit adds a hash to do so.  It
also fixes the problem that choices may become ambiguous by allowing
screen overflow in this case and removes a redundant `if defined
$value` conditional.

Signed-off-by: Kevin Locke <ke...@kevinlocke.name>
---
 Debconf/Element/Dialog/Multiselect.pm | 13 ++++++++++++-
 Debconf/Element/Dialog/Select.pm      | 13 ++++++++++++-
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/Debconf/Element/Dialog/Multiselect.pm b/Debconf/Element/Dialog/Multiselect.pm
index 781655c7..d3b6e4cf 100644
--- a/Debconf/Element/Dialog/Multiselect.pm
+++ b/Debconf/Element/Dialog/Multiselect.pm
@@ -10,6 +10,7 @@ package Debconf::Element::Dialog::Multiselect;
 use strict;
 use base qw(Debconf::Element::Multiselect);
 use Debconf::Encoding qw(width);
+use Debconf::Log qw(debug);
 
 =head1 DESCRIPTION
 
@@ -53,8 +54,18 @@ sub show {
 	$lines=$lines + $menu_height + $this->frontend->spacer;
 	my $selectspacer = $this->frontend->selectspacer;
 	my $c=1;
+	my %unellipsized;
 	foreach (@choices) {
 		my $choice = $this->frontend->ellipsize($_);
+
+		if (exists $unellipsized{$choice}) {
+		    debug 'developer' => sprintf
+			'Ambiguous ellipsized choice "%s": "%s" or "%s".  Overflow.',
+			$choice, $unellipsized{$choice}, $_;
+		    $choice = $_;
+		}
+		$unellipsized{$choice} = $_;
+
 		push @params, ($choice, "");
 		push @params, ($value{$_} ? 'on' : 'off');
 
@@ -78,7 +89,7 @@ sub show {
 		# Dialog returns the selected items, each on a line.
 		# Translate back to C, and turn into our internal format.
 		$this->value(join(", ", $this->order_values(
-					map { $this->translate_to_C($_) }
+					map { $this->translate_to_C($unellipsized{$_}) }
 					split(/\n/, $value))));
 	}
 	else {
diff --git a/Debconf/Element/Dialog/Select.pm b/Debconf/Element/Dialog/Select.pm
index 2dec49a4..b873750f 100644
--- a/Debconf/Element/Dialog/Select.pm
+++ b/Debconf/Element/Dialog/Select.pm
@@ -10,6 +10,7 @@ package Debconf::Element::Dialog::Select;
 use strict;
 use base qw(Debconf::Element::Select);
 use Debconf::Encoding qw(width);
+use Debconf::Log qw(debug);
 
 =head1 DESCRIPTION
 
@@ -44,8 +45,18 @@ sub show {
 	$lines=$lines + $menu_height + $this->frontend->spacer;
 	my $c=1;
 	my $selectspacer = $this->frontend->selectspacer;
+	my %unellipsized;
 	foreach (@choices) {
 		my $choice = $this->frontend->ellipsize($_);
+
+		if (exists $unellipsized{$choice}) {
+		    debug 'developer' => sprintf
+			'Ambiguous ellipsized choice "%s": "%s" or "%s".  Overflow.',
+			$choice, $unellipsized{$choice}, $_;
+		    $choice = $_;
+		}
+		$unellipsized{$choice} = $_;
+
 		push @params, $choice, '';
 		
 		# Choices wider than the description text? (Only needed for
@@ -64,7 +75,7 @@ sub show {
 
 	my $value=$this->frontend->showdialog($this->question, @params);
 	if (defined $value) {
-		$this->value($this->translate_to_C($value)) if defined $value;
+		$this->value($this->translate_to_C($unellipsized{$value}));
 	}
 	else {
 		my $default='';
-- 
2.20.1

Reply via email to