File: Multiselect.pm

package info (click to toggle)
debconf 1.5.91
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,180 kB
  • sloc: perl: 8,500; sh: 262; python: 182; makefile: 144
file content (104 lines) | stat: -rw-r--r-- 2,959 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/perl

=head1 NAME

Debconf::Element::Dialog::Multiselect - a check list in a dialog box

=cut

package Debconf::Element::Dialog::Multiselect;
use warnings;
use strict;
use base qw(Debconf::Element::Multiselect);
use Debconf::Encoding qw(width);
use Debconf::Log qw(debug);

=head1 DESCRIPTION

This is an input element that can display a dialog box with a check list in
it.

=cut

sub show {
	my $this=shift;

	# Figure out how much space in the dialog box the prompt will take.
	# The -2 tells makeprompt to leave at least two lines to use to
	# display the list.
	my ($text, $lines, $columns)=
		$this->frontend->makeprompt($this->question, -2);

	my $screen_lines=$this->frontend->screenheight - $this->frontend->spacer;
	my @params=();
	my @choices=$this->question->choices_split;
	my %value = map { $_ => 1 } $this->translate_default;

	# Figure out how many lines of the screen should be used to
	# scroll the list. Look at how much free screen real estate
	# we have after putting the description at the top. If there's
	# too little, the list will need to scroll.
	my $menu_height=$#choices + 1;
	if ($lines + $#choices + 2 >= $screen_lines) {
		$menu_height = $screen_lines - $lines - 4;
		if ($menu_height < 3 && $#choices + 1 > 2) {
			# Don't display a tiny menu.
			$this->frontend->showtext($this->question, $this->question->extended_description);
			($text, $lines, $columns)=$this->frontend->sizetext($this->question->description);
			$menu_height=$#choices + 1;
			if ($lines + $#choices + 2 >= $screen_lines) {
				$menu_height = $screen_lines - $lines - 4;
			}
		}
	}

	$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');

		# Choices wider than the description text? (Only needed for
		# whiptail BTW.)
		if ($columns < width($choice) + $selectspacer) {
			$columns = width($choice) + $selectspacer;
		}
	}

	if ($this->frontend->dashsep) {
		unshift @params, $this->frontend->dashsep;
	}

	@params=('--separate-output', '--checklist',
	         $text, $lines, $columns, $menu_height, @params);

	my $value=$this->frontend->showdialog($this->question, @params);

	if (defined $value) {
		# 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($unellipsized{$_}) }
					split(/\n/, $value))));
	}
	else {
		my $default='';
		$default=$this->question->value
			if defined $this->question->value;
		$this->value($default);
	}
}

1