1 # Functions that handle calling dialog(1) -*-perl-*-
2 # $Id: dialog.pl,v 1.18 2018/06/12 21:01:58 tom Exp $
3 ################################################################################
4 # Copyright 2018 Thomas E. Dickey
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU Lesser General Public License, version 2.1
8 # as published by the Free Software Foundation.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this program; if not, write to
17 # Free Software Foundation, Inc.
18 # 51 Franklin St., Fifth Floor
19 # Boston, MA 02110, USA.
20 ################################################################################
21 # The "rhs_" functions, as well as return_output originally came from Redhat
23 # http://www.ibiblio.org/pub/historic-linux/distributions/redhat-4.0/i386/live/usr/bin/Xconfigurator.pl
24 # The other functions were added to make this more useful for demonstrations.
26 # These comments are from the original file:
27 #------------------------------------------------------------------------------
28 # Return values are 1 for success and 0 for failure (or cancel)
29 # Resultant text (if any) is in dialog_result
31 # Unfortunately, the gauge requires use of /bin/sh to get going.
32 # I didn't bother to make the others shell-free, although it
33 # would be simple to do.
35 # Note that dialog generally returns 0 for success, so I invert the
36 # sense of the return code for more readable boolean expressions.
37 #------------------------------------------------------------------------------
43 our $DIALOG = "dialog";
55 if ( open TRACE, ">>dialog.log" ) {
56 printf TRACE $_[0], @_[ 1 .. $#_ ];
64 $text =~ s/[\r\n]+/\n/g;
65 $text =~ s/[^\n\t -~]/?/g;
66 $text =~ s/([\\"])/\\$1/g;
67 return sprintf "\"%s\"", $text;
71 my $params = `$DIALOG --stdout --print-maxsize`;
73 $params =~ s/^[^:]*:\s+//;
74 my @params = split /,\s+/, $params;
75 if ( $#params == 1 ) {
76 $scr_lines = $params[0];
77 $scr_cols = $params[1];
89 "$DIALOG --stdout --print-text-size "
91 . " $scr_lines $width 2>&1";
92 my $params = `$command`;
93 my @params = split( /\s/, $params );
98 return system("$DIALOG --clear");
102 my ( $title, $file, $width, $height ) = @_;
104 $width = int($width);
105 $height = int($height);
106 system( "$DIALOG --title "
108 . " --textbox $file $height $width" );
114 my ( $title, $message, $width ) = @_;
115 my ( $tmp, $height );
117 $width = int($width);
118 $message = &rhs_wordwrap( $message, $width );
119 $height = 5 + &height_of( $width, $message );
122 system( "$DIALOG --title "
126 . " $height $width" );
136 my ( $title, $message, $width ) = @_;
137 my ( $tmp, $height );
139 $width = int($width);
140 $message = &rhs_wordwrap( $message, $width );
141 $height = 2 + &height_of( $width, $message );
144 system( "$DIALOG --title "
148 . " $height $width" );
152 my ( $title, $message, $width ) = @_;
153 my ( $tmp, $height );
155 $width = int($width);
156 $message = &rhs_wordwrap( $message, $width );
157 $height = 4 + &height_of( $width, $message );
160 system( "$DIALOG --title "
164 . " $height $width" );
166 # Dumb: dialog returns 0 for "yes" and 1 for "no"
176 my ( $title, $message, $width, $percent ) = @_;
177 my ( $tmp, $height );
179 $width = int($width);
180 $gauge_width = $width;
182 $message = &rhs_wordwrap( $message, $width );
183 $height = 5 + &height_of( $width, $message );
190 . " $height $width $percent" );
193 sub rhs_update_gauge {
196 &printflush( $GAUGE, "$percent\n" );
199 sub rhs_update_gauge_and_message {
200 my ( $message, $percent ) = @_;
202 $message = &rhs_wordwrap( $message, $gauge_width );
203 $message =~ s/\n/\\n/g;
204 &printflush( $GAUGE, "XXX\n$percent\n$message\nXXX\n" );
212 my ( $title, $message, $width, $instr ) = @_;
213 my ( $tmp, $height );
215 $width = int($width);
216 $message = &rhs_wordwrap( $message, $width );
217 $height = 7 + &height_of( $width, $message );
219 return &return_output( 0,
229 my ( $title, $message, $width, $numitems ) = @_;
230 my ( $i, $tmp, $ent, $height, $listheight, $menuheight, @list );
232 $width = int($width);
233 $numitems = int($numitems);
241 for ( $i = 0 ; $i < $numitems ; $i++ ) {
243 $list[@list] = "ed($ent);
245 $list[@list] = "ed($ent);
248 $message = &rhs_wordwrap( $message, $width );
249 $listheight = &height_of( $width, $message );
250 $height = 6 + $listheight + $numitems;
252 if ( $height <= $scr_lines ) {
253 $menuheight = $numitems;
256 $height = $scr_lines;
257 $menuheight = $scr_lines - $listheight - 6;
260 return &return_output( 0,
265 . " $height $width $menuheight @list" );
269 my ( $title, $message, $width, $numitems ) = @_;
270 my ( $i, $tmp, $ent, $height, $listheight, $menuheight, @list );
272 $width = int($width);
273 $numitems = int($numitems);
281 for ( $i = 0 ; $i < $numitems ; $i++ ) {
283 $list[@list] = "ed($ent);
284 $list[@list] = "ed("");
287 $message = &rhs_wordwrap( $message, $width );
288 $listheight = &height_of( $width, $message );
289 $height = 6 + $listheight + $numitems;
291 if ( $height <= $scr_lines ) {
292 $menuheight = $numitems;
295 $height = $scr_lines;
296 $menuheight = $scr_lines - $listheight - 6;
299 return &return_output( 0,
304 . " $height $width $menuheight @list" );
308 my ( $title, $message, $width, %items ) = @_;
309 my ( $tmp, $ent, $height, $listheight, $menuheight, @list );
311 $width = int($width);
313 foreach $ent ( sort keys(%items) ) {
314 $list[@list] = "ed($ent);
315 $list[@list] = "ed( $items{$ent} );
318 my $numitems = keys(%items);
319 $message = &rhs_wordwrap( $message, $width );
320 $listheight = &height_of( $width, $message );
321 $height = 6 + $listheight + $numitems;
323 if ( $height <= $scr_lines ) {
324 $menuheight = $numitems;
327 $height = $scr_lines;
328 $menuheight = $scr_lines - $listheight - 6;
331 return &return_output( 0,
336 . " $height $width $menuheight @list" );
340 my ( $title, $message, $width, $numitems ) = @_;
341 my ( $i, $tmp, $ent, $height, $listheight, $menuheight, @list );
343 $width = int($width);
344 $numitems = int($numitems);
352 for ( $i = 0 ; $i < $numitems ; $i++ ) {
354 $list[@list] = "ed($ent);
356 $list[@list] = "ed($ent);
362 $list[@list] = "OFF";
366 $message = &rhs_wordwrap( $message, $width );
367 $listheight = &height_of( $width, $message );
368 $height = 6 + $listheight + $numitems;
370 if ( $height <= $scr_lines ) {
371 $menuheight = $numitems;
374 $height = $scr_lines;
375 $menuheight = $scr_lines - $listheight - 6;
378 return &return_output( "list",
381 . " --separate-output --checklist "
383 . " $height $width $menuheight @list" );
387 my ( $title, $message, $width, $numitems ) = @_;
388 my ( $i, $tmp, $ent, $height, $listheight, $menuheight, @list );
390 $width = int($width);
391 $numitems = int($numitems);
399 for ( $i = 0 ; $i < $numitems ; $i++ ) {
401 $list[@list] = "ed($ent);
402 $list[@list] = "ed("");
403 $list[@list] = "OFF";
406 $message = &rhs_wordwrap( $message, $width );
407 $listheight = &height_of( $width, $message );
408 $height = 6 + $listheight + $numitems;
410 if ( $height <= $scr_lines ) {
411 $menuheight = $numitems;
414 $height = $scr_lines;
415 $menuheight = $scr_lines - $listheight - 6;
417 return &return_output( "list",
420 . " --separate-output --checklist "
422 . " $height $width $menuheight @list" );
426 my ( $title, $message, $width, %items ) = @_;
427 my ( $tmp, $ent, $height, $listheight, $menuheight, @list );
435 foreach $ent ( sort keys(%items) ) {
436 $list[@list] = "ed($ent);
437 $list[@list] = "ed( $items{$ent} );
438 $list[@list] = "OFF";
441 my $numitems = keys(%items);
442 $message = &rhs_wordwrap( $message, $width );
443 $listheight = &height_of( $width, $message );
444 $height = 6 + $listheight + $numitems;
446 if ( $height <= $scr_lines ) {
447 $menuheight = $numitems;
450 $height = $scr_lines;
451 $menuheight = $scr_lines - $listheight - 6;
454 return &return_output( "list",
457 . " --separate-output --checklist "
459 . " $height $width $menuheight @list" );
463 my ( $title, $message, $width, $numitems ) = @_;
464 my ( $i, $tmp, $ent, $height, $listheight, $menuheight, @list );
466 $width = int($width);
467 $numitems = int($numitems);
475 for ( $i = 0 ; $i < $numitems ; $i++ ) {
477 $list[@list] = "ed($ent);
479 $list[@list] = "ed($ent);
485 $list[@list] = "OFF";
489 $message = &rhs_wordwrap( $message, $width );
490 $listheight = &height_of( $width, $message );
491 $height = 6 + $listheight + $numitems;
493 if ( $height <= $scr_lines ) {
494 $menuheight = $numitems;
497 $height = $scr_lines;
498 $menuheight = $scr_lines - $listheight - 6;
501 return &return_output( 0,
506 . " $height $width $menuheight @list" );
510 my ( $listp, $command ) = @_;
513 pipe( PARENT_READER, CHILD_WRITER );
515 # We have to fork (as opposed to using "system") so that the parent
516 # process can read from the pipe to avoid deadlock.
518 if ( $pid == 0 ) { # child
519 close(PARENT_READER);
520 open( STDERR, ">&CHILD_WRITER" );
524 if ( $pid > 0 ) { # parent
528 while (<PARENT_READER>) {
530 $dialog_result[@dialog_result] = $_;
534 @dialog_result = <PARENT_READER>;
536 close(PARENT_READER);
541 # Again, dialog returns results backwards
551 my ( $intext, $width ) = @_;
552 my ( $outtext, $i, $j, @lines, $wrap, @words, $pos, $pad );
554 &trace( "rhs_wordwrap\n\tintext:%s\n\twidth:%d\n", $intext, $width );
556 $width = int($width);
558 $pad = 3; # leave 3 spaces around each line
559 $pos = $pad; # current insert position
560 $wrap = 0; # 1 if we have been auto wrapping
561 my $insert_nl = 0; # 1 if we just did an absolute
562 # and we should preface any new text
564 @lines = split( /\n/, $intext );
566 for ( $i = 0 ; $i <= $#lines ; $i++ ) {
568 if ( $lines[$i] =~ /^>/ ) {
569 $outtext .= "\n" if ($insert_nl);
570 $outtext .= "\n" if ($wrap);
571 $lines[$i] =~ /^>(.*)$/;
579 @words = split( /\s+/, $lines[$i] );
580 for ( $j = 0 ; $j <= $#words ; $j++ ) {
585 if ( ( length( $words[$j] ) + $pos ) > $width - $pad ) {
589 $outtext .= $words[$j] . " ";
590 $pos += length( $words[$j] ) + 1;
595 &trace( "\touttext:%s\n", $outtext );