The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

UDPM - Perl extension for User Dialogs

SYNOPSIS

  use UDPM;
  my $d = new UDPM ({'backtitle'=>'Demo','colours'=>1,'cr-wrap'=>1,
                     'height'=>20,'width'=>70,'list-height'=>5,
                     'no-shadows'=>1});

  $d->msgbox({'title'=>'Welcome!',
              'text'=>'[B]Welcome[/B] [U]one[/U] and [R]all[/R]!'});

ABSTRACT

UserDialogPerlModule is simply an OOPerl wrapper for the dialog application(s). This version of UDPM supports dialog, cdialog (aka: dialog ver. 0.9b), whiptail, gdialog and kdialog. There is also an ASCII dialog mode (as a fallback for systems without a dialog variant).

DESCRIPTION

UDPM strives to be full-featured and robust in everything to do with simple end-user interfaces. Care has been taken to provide a clean OO interface to common command line utilities as well as providing a native ascii mode simulating the various interface widgets.

EXPORT

Nothing.

PACKAGE METHODS

new()

EXAMPLE
     my $d = new(\%my_defaults);
DESCRIPTION

    This is the Class Constructor method. The only argument it takes is a hash reference containing valid configuration keys and values. See REGARDING ATTRIBUTES below for more details. A UDPM object reference with the defaults defined in the arguments is returned. These defaults are overridable on a per method call basis.

state()

EXAMPLE
     while ($d->state() ne "ESC" || $d->state() ne "CANCEL") {
       ...
     }
DESCRIPTION

    This method returns a string describing the last exit state of any widget. Valid states are: "OK" "ESC" "CANCEL" "EXTRA" "HELP" "UNKNOWN".

rv()

EXAMPLE
     exit($d->rv());
DESCRIPTION

    This returns the last return value (aka: exit value) for the last widget displayed.

rs()

EXAMPLE
     $d->inputbox({'text'=>'testing'});
     my $input = $d->rs();
DESCRIPTION

    This returns the last return strign (aka: user-input) for the last widget displayed. Some widgets do not have a return string and instead have a return array.

ra()

EXAMPLE
     $d->checklist({'text'=>'test','menu'=>['1','one','off','2','two','off']});
     my @selected = $d->ra();
DESCRIPTION

    This returns the last return array (aka: multi-user-input) for the last widget displayed. Some widgets do not have a return array and instead have a return string.

attribute()

EXAMPLE
     $d->attribute({'attr'=>'val','attr2'=>'val2'});
     $d->attribute('attr','val');
     my $val = $d->attribute('attr');
DESCRIPTION

    This method will alter the defaults within the UDPM object. There are three ways to use this method. The first is to pass a hash reference containing all the attribute -> value pairs to be altered. The second is to pass two scalars, the first is the attibute name, and the second is the value to set it to. The third is to simply pass only the name of an attribute and it will return that attribute's current value.

is_attr()

EXAMPLE
     print "has attribute" if $d->is_attr('attribute');
DESCRIPTION

    The only argument is the name of a desired attribute. Returns TRUE (1) if the argument is a valid atrribute and FALSE (0) if the argument is not.

is_linux()

EXAMPLE
     print "you're running Linux!\n" if $d->is_linux();
DESCRIPTION

    This is a very simple method that returns 1 if $^O contains "linux".

is_bsd()

EXAMPLE
     print "you're running BSD!\n" if $d->is_bsd();
DESCRIPTION

    This is a very simple method that returns 1 if $^O contains "bsd".

is_ascii()

EXAMPLE
     print "you're using the native (ascii) dialog mode!\n" if $d->is_ascii();
DESCRIPTION

    This is a very simple method that returns 1 if the dialog type is the native (ascii) dialog. This dialog type is binary-independant thus making this module more versatile as it no longer depends on the worlds outside of Perl.

is_dialog()

EXAMPLE
     print "you're using the origional dialog!\n" if $d->is_dialog();
DESCRIPTION

    This is a very simple method that returns 1 if the dialog type is the origional dialog.

is_cdialog()

EXAMPLE
     print "you're using the (ComeOn) dialog v0.9!\n" if $d->is_cdialog();
DESCRIPTION

    This is a very simple method that returns 1 if the dialog type is the (ComeOn) dialog v0.9.

is_whiptail()

EXAMPLE
     print "you're using whiptail!\n" if $d->is_cdialog();
DESCRIPTION

    This is a very simple method that returns 1 if the dialog type is whiptail.

is_gdialog()

EXAMPLE
     print "you're using the Gtk/Gnome dialog!\n" if $d->is_gdialog();
DESCRIPTION

    This is a very simple method that returns 1 if the dialog type is the Gtk/Gnome dialog.

is_kdialog()

EXAMPLE
     print "you're using the KDE dialog!\n" if $d->is_kdialog();
DESCRIPTION

    This is a very simple method that returns 1 if the dialog type is the KDE dialog.

WIDGET METHODS

clear()

EXAMPLE
     $d->clear();
DESCRIPTION

    This method caches the output of a `clear` and simply prints that whenever called. This does nothing with gui-based dialog variants.

infobox()

EXAMPLE
     $d->infobox({'text'=>'example','sleep'=>1});
DESCRIPTION

    This method displays the infobox widget. The 'sleep' attribute is available for _all_ widgets but is most commonly used with infobox(). This widget behaves differently depending on the dialog variation used. Of special note is whiptail which will simply diaplay and exit which for the most part is what you want but when using whiptail in an X session (via an xterm for instance) the screen will clear right away and the message is lost. The only work-around for this is to check for the 'DISPLAY' environemnt variable if whiptail is being used and substitute the infobox widget with a msgbox; which UDPM does automagically.

msgbox()

EXAMPLE
     $d->msgbox({'text'=>'example'});
DESCRIPTION

    This method displays the msgbox widget.

textbox()

EXAMPLE
     $d->textbox({'file'=>'/path/and/file/name'});
DESCRIPTION

    This method displays the textbox widget (which in turn displays the specified text file).

yesno()

EXAMPLE
     if ($d->yesno({'text'=>'A question?'})) {
       # answer is YES
     } else {
       # answer is NO or ESC/CANCEL
     }
DESCRIPTION

    This method presents the yesno widget and waits for a response. Returns TRUE (1) if the user selected <Yes> and returns FALSE (0) if the user selected <No> or pressed the escape button (in which case $d->state() ne "OK").

noyes()

EXAMPLE
     if ($d->noyes({'text'=>'A question?'})) {
       # answer is YES
     } else {
       # answer is NO or ESC/CANCEL
     }
DESCRIPTION

    This method is identical to the yesno() widget with the exception that the <No> button is initially selected for the user. This is the equivalent of $d->yesno({'text'=>'default no','defaultno'=>1}). Returns TRUE (1) if the user selected <Yes> and returns FALSE (0) if the user selected <No> or pressed the escape button (in which case $d->state() ne "OK").

inputbox()

EXAMPLE
     my $str = $d->inputbox({'text'=>'enter some text',
                             'init'=>'this is in the input field'});
DESCRIPTION

    This displays the inputbox widget and returns the user data as a string.

passwordbox()

EXAMPLE
     my $pwd = $d->passwordbox({'text'=>'notice no text as you type...'});
DESCRIPTION

    This displays the passwordbox widget and returns the user data as a string. Notice that this is identical to the inputbox() widget except that this one does not display _any_ text as the user types it in (not even ***'s).

EXAMPLE
     my $item = $d->menu({'text'=>'example menu',
                          'menu'=>[ 'tag1', 'item 1 description',
                                    'tag2', 'item 2 description'
                                  ]});
DESCRIPTION

    This displays the menubox widget and returns the "tag" of the item selected. Each menu() item is made up of two elements of an array. The first is the "tag" which is returned upon selection and the second is the item's description.

radiolist()

EXAMPLE
     my $item = $d->radiolist({'text'=>'a list',
                               'menu'=>[ 'tag1', 'item 1 desc', 'off',
                                         'tag2', 'item 2 desc', 'on'
                                       ]});
DESCRIPTION

    This is very similar to the menu() widget except that the radiolist() menu definiton is slightly different. Each radiolist() item is made up of three consecutive elements of an array. The first is the "tag" which is returned upon selection. The second is the description of the item and the third is a state toggle, either 'on' or 'off' to specify which is selected first (if multiple are specified as 'on' then the first instance of 'on' is the item initially selected).

checklist()

EXAMPLE
     my $item = $d->checklist({'text'=>'a list',
                               'menu'=>[ 'tag1', 'item 1 desc', 'off',
                                         'tag2', 'item 2 desc', 'on'
                                       ]});
DESCRIPTION

    This is very similar to the radiolist() widget except that the checklist() allows for multiple selections from the menu. Each checklist() item is made up of three consecutive elements of an array. The first is the "tag" which is returned upon selection. The second is the description of the item and the third is a state toggle, either 'on' or 'off' to specify which is selected (all that are marked 'on' will be selected initially). This will return a list of all the selected "tag"s.

start_gauge()

EXAMPLE
     $d->start_gauge({'text'=>'look Ma, a meter bar!','percent'=>10});
DESCRIPTION

    This method starts the gauge widget and enables the use of the other gauge related methods. The attribute 'percent' indicates the initial value of the gauge. This is NOT a blocking method in that it will start the widget and the Perl continues on with the gauge widget being displayed. This will return 254 if there is a gauge widget already open.

msg_gauge()

EXAMPLE
     $d->msg_gauge("a new message");
DESCRIPTION

    This method updates a gauge widget's text message area with a new string. This will return 254 if there is no gauge widget currently open.

inc_gauge()

EXAMPLE
     $d->inc_gauge(5);
DESCRIPTION

    This method increments a gauge widget's value by the amount specified. This will return 254 if there is no gauge widget currently open.

set_gauge()

EXAMPLE
     $d->set_gauge(75);
DESCRIPTION

    This method sets a gauge widget's value to the amount specified. This will return 254 if there is no gauge widget currently open.

end_gauge()

EXAMPLE
     $d->end_gauge();
DESCRIPTION

    This method closes an open gauge widget. This will return 254 if there is no gauge widget currently open.

tailbox()

EXAMPLE
     $d->tailbox({'file'=>'/path/and/file/name'});
DESCRIPTION

    This method displays a tailbox widget with the file specified. Basically a glorified `tail -f` :) This method will check the file for read permission and if there is no permission to read the file, a msgbox widget is displayed with an appropriate error message.

fselect()

EXAMPLE
     my $name = $d->fselect({'path'=>'/'});
DESCRIPTION

    This method displays an fselect (File Selection) widget and returns the user data as a string.

timebox()

EXAMPLE
     my ($hour,$minute,$second) = $d->timebox({'hour'=>'4',
                                               'minute'=>'20',
                                               'second'=>'0'});
DESCRIPTION

    This method displays a timebox() widget and returns a list of the user specified time. If any of the 'hour', 'minute' or 'second' are not specified the widget will display the system's current time instead. Quoting the time values should help prevent any sytactical problems with the number zero.

calendar()

EXAMPLE
     my ($day,$month,$year) = $d->calendar({'day'=>'20',
                                            'month'=>'4',
                                            'year'=>'2002'});
DESCRIPTION

    This method displays a calendar() widget and returns a list of the user specified date. If any of the 'day', 'month' or 'year' are not specified the widget will display the system's current date instead. Quoting the date values should help prevent any sytactical problems with the number zero.

ascii_spinner()

EXAMPLE
     while (1) {
       print $d->ascii_spinner();
       `sleep 0.2`; #slow it down so we can see it rotate...
     }
DESCRIPTION

    This method returns the next character for an ascii spinner. Note that this will return a backspace character ("\b") along with one of the following four characters: | / - \

    It is left as an exercise to the end-user how to utilize the spinner best in their application.

REGARDING ATTRIBUTES

    Almost all methods in this class work with a single argument of a hash reference containing any attibute => value pairs. These attributes are for the most part taken straight from the dialog application's command line options. There are some that have been omitted (like separate-output because those are only usefull in determining user input) and others that may not work with all dialog application variations (like whiptail). UDPM will intelligently assign the command line options depending on the type of dialog in use. This means that you don't have to worry about which attribute to use and when, simply use it and if it's not applicable to the widget / dialog variation; it won't be used. The following is not 100% accurate but none the less useful.

     +-------------------------------------------------------+
     |              /Dialog__________________________________|
     |              |   /cDialog_____________________________|
     |              |   |   /Whiptail________________________|
     |              |   |   |   /(g|k)Dialog_________________|
     |              |   |   |   |   /native_mode_____________|
     +--------------+   |   |   |   |   /--------------------+
     | attribute    |   |   |   |   |   |                    |
     +--------------+---+---+---+---+---+--------------------+
     | title        | X | X | X | X | X |                    |
     | backtitle    | X | X | X | X | X |                    |
     | height       | X | X | X | X | X |                    |
     | width        | X | X | X | X | X |                    |
     | list-height  | X | X | X | X | X |                    |
     | defaultno    | X | X | X | X | X |                    |
     | clear        | X | X | X | X | X |                    |
     | nocancel     | X | X | X |   | X |                    |
     | fb           |   |   | X |   |   |                    |
     | noitem       |   |   | X |   |   |                    |
     | scrolltext   |   |   | X |   |   |                    |
     | aspect       |   | X |   |   |   |                    |
     | beep         | * | X | * | * | * |                    |
     | beep-after   |   | X |   |   |   |                    |
     | begin        |   | X |   |   |   |                    |
     | cancel-label |   | X |   |   | X |                    |
     | colours      |   | X |   |   |   |                    |
     | cr-wrap      |   | X |   |   |   |                    |
     | default-item |   | X |   |   |   |                    |
     | exit-label   |   | X |   |   |   |                    |
     | extra-button |   | X |   |   | X |                    |
     | extra-label  |   | X |   |   | X |                    |
     | help-button  |   | X |   |   | X |                    |
     | help-label   |   | X |   |   | X |                    |
     | ignore       |   | X |   |   |   |                    |
     | item-help    |   | X |   |   |   |                    |
     | max-input    |   | X |   |   | X |                    |
     | no-collapse  |   | X |   |   |   |                    |
     | no-shadow    |   | X |   |   |   |                    |
     | ok-label     |   | x |   |   |   |                    |
     | shadow       |   | X |   |   |   |                    |
     | sleep        | * | X | * | * | * |                    |
     | tab-correct  |   | X |   |   |   |                    |
     | tab-len      |   | X |   |   |   |                    |
     | timeout      |   | X |   |   |   |                    |
     | trim         |   | X |   |   |   |                    |
     +--------------+---+---+---+---+---+--------------------+
     | Module Specific Attributes                            |
     +--------------+----------------------------------------+
     | dialogrc     | set DIALOGRC to this file              |
     | dialogbin    | force a certain binary...              |
     | envpaths     | array ref with bin paths               |
     | variants     | array ref dialog, whiptail             |
     | gui-variants | array ref gdialog, kdialog             |
     | ascii        | set to 1 to force ascii mode           |
     | auto-clear   | force a clear screen after each widget |
     | auto-scale   | auto-adjust width of 'text' widgets    |
     | max-scale    | upper limit of line size (auto-scale)  |
     | pager        | force a certain pager for ascii mode   |
     | tail         | force a tail binary for ascii mode     |
     | tailopt      | specify the tail continuous read opt.  |
     | tmpdir       | path to a valid temp directory         |
     | sttybin      | path to an stty binary                 |
     | use_stderr   | make ascii mode output to stderr       |
     | tmpdir       | path to a valid temp directory         |
     +--------------+----------------------------------------+
     | Callback Attributes                                   |
     +--------------+----------------------------------------+
     | HELP-SUB     | a coderef evaluated on "HELP" signal   |
     | EXTRA-SUB    | a coderef evaluated on "EXTRA" signal  |
     | ESC-SUB      | a coderef evaluated on "ESC" signal    |
     | CANCEL-SUB   | a coderef evaluated on "CANCEL" signal |
     +--------------+----------------------------------------+

    * = sleep and beep are handled by UDPM instead of the dialog variant. At the moment the only dialog variant that supports these argumments is cDialog.

REGARDING 'Module Specific' ATTRIBUTES

    These attributes are only used once during object construction and cannot be modified during the life of the object (this may change in future versions).

dialogrc => '/path/to/dialogrc'

    Specify this if you want cDialog to use a certain resource configuration file. cDialog is the only dialog variant that can use this option effectively.

dialogbin => '/path/to/dialog'

    By specifying the full path and filename you can force UDPM to use a specific binary. If this is omitted, UDPM will determine the binary to use automatically. If you specify an invalid binary here, UDPM will exit() and print to STDERR an error message indicating that it couldn't find a dialog binary. Unless you want to force a specific binary to be used, do not set this attribute.

envpath => [ '/bin', '/usr/bin', '/usr/local/bin' ]

    If no PATH environemnt variable is present during autodetection of the dialog binary, this list is used to search for a valid variant of dialog. Do not change this unless you know what you are doing.

variants => [ 'dialog', 'whiptail' ]

    This is a list of the names of the various dialog variant binaries. Do not change this unless you know what you are doing.

gui-variants => [ 'gdialog', 'kdialog' ]

    This is a list of the names of the various gui based dialog variant binaries like gdialog and kdialog. Do not change this unless you know what you are doing.

ascii => 0

    Set this to "1" to force the use of native ASCII to mimic various dialog widgets.

auto-clear => 0

    Set this to "1" to force a $d->clear() after every widget.

auto-scale => 0

    Set this to "1" to have the width of the dialogs dynamically altered for long 'text' lines. See 'max-scale' for more details.

max-scale => 78

    This is the max number of characters in a line that can affect the 'width' attribute for 'auto-scale'ing a widget. If the 'width' (-5 for borders) is less than the length of the line of text and the length of the line of text is less than the 'max-scale'; the attribute 'width' will be temporarialy adjusted, otherwise that line will have no affect on the 'width' and it's left up to the dialog variant to wrap that text line appropriately. In the case that the user is using cDialog (which has a '--print-maxsize'), the maximum scale size is automatically adjusted to the available limit (this overrides and 'max-scale' setting during construction).

pager => '/usr/bin/pager'

    Set this to the desired pager (default is /usr/bin/pager) for the textbox in ascii mode. If the environment variable 'PAGER' exists it will be used instead of the default / preset.

tail => '/usr/bin/tail'

    Set this to the desired tail application.

tailopt => '-f'

    Set this to the desired tail application's "constantly read from file" command line option.

sttybin => '/bin/stty'

    stty is the application used to manipulate the tty of the ascii-mode passwordbox widget.

use_stderr => 0

    Set this to anything other than '0' (zero) and the ascii-mode widgets will print their interfaces to STDERR instead of STDOUT. This does not interfere with STDIN which is still used for input.

tmpdir => '/tmp'

    This is used with variants like whiptail that do not play well with redirecting their output (using the normal conventions). All temporary files are deleted but if the user performs a "harsh-break" (hitting ctrl+c many times etc.) there is a chance that some null files may be left around.

REGARDING 'Callback' ATTRIBUTES

    These attributes are only used once during object construction and cannot be modified during the life of the object (this may change in future versions). These 'Callback' functions are simply signal handlers for the four main signals; "HELP", "EXTRA", "ESC", and "CANCEL".

    When using these 'Callback' functions be sure to use a secondary UDPM object within them instead of calling widgets with the same UDPM object that these callbacks are being assigned to. When you do use the same object in the callbacks the state() and other such variables _are_ modified and this can cause logical problems. Having a secondary UDPM object just for the callbacks isn't a "Bad Thing (tm)" but does add overhead.

HELP-SUB => \&HELP_SUB_FUNC

    This code block will be evaluated every time the user selects an available "Help" button.

EXTRA-SUB => \&EXTRA_SUB_FUNC

    This code block will be evaluated every time the user selects an available "Extra" button (regardless of it's label value).

ESC-SUB => \&ESC_SUB_FUNC

    This code block will be evaluated every time the user presses (or selects) the "Esc" button.

CANCEL-SUB => \&CANCEL_SUB_FUNC

    This code block will be evaluated every time the user selects an available "Cancel" button (regardless of it's label value).

REGARDING 'text' ATTRIBUTE

    This attribute is special in that you can use it in two forms; scalar and array. Here is some examples to help clarify usage:

     $d->msgbox({'text'=>['line one','line two','line three']});
        +---------------------------------+
        | line one                        |
        | line two                        |
        | line three                      |
        +---------------------------------+
    
     $d->msgbox({'text'=>'line one\nline two\nline three'});
        +---------------------------------+
        | line one                        |
        | line two                        |
        | line three                      |
        +---------------------------------+

    The dialog variant ComeOn Dialog (aka: dialog ver. 0.9b) supports the use of interesting colour related attributes which UDPM takes full advantage of. When using any widget with a 'text' attribute, the text itself is allowed certain colour formatting sequences. UDPM will translate all 'text' attributes and depending on the 'colours' attribute (1 or 0) and also on the dialog variant either strip away the formatting sequences or replace them with the "real" sequences. The "reset all" effect resets all effects including colours. The following tables should enlighten the situation.

     +-----------+------------+-----------+
     | effect    | UDPM       | REAL      |
     +-----------+------------+-----------+
     | bold      | [B]...[/B] | \Zb...\ZB |
     | underline | [U]...[/U] | \Zu...\ZU |
     | reversed  | [R]...[/R] | \Zr...\ZR |
     | reset all | [N]        | \Zn       |
     +-----------+------------+-----------+
    
     +---------+-------------+------+
     | color   | UDP         | REAL |
     +---------+-------------+------+
     | black   | [C=black]   | \Z0  |
     | red     | [C=red]     | \Z1  |
     | green   | [C=green]   | \Z2  |
     | yellow  | [C=yellow]  | \Z3  |
     | blue    | [C=blue]    | \Z4  |
     | magenta | [C=magenta] | \Z5  |
     | cyan    | [C=cyan]    | \Z6  |
     | white   | [C=white]   | \Z7  |
     +---------+-------------+------+
    
     +-----------+------------+-------+
     | alignment | Long       | Short |
     +-----------+------------+-------+
     | centered  | [A=CENTER] | [A=C] |
     | left      | [A=LEFT]   | [A=L] |
     | right     | [A=RIGHT]  | [A=R] |
     +-----------+------------+-------+

    Either the REAL or UDPM versions can be used. The UDPM sequences are case in-sensitive, and the REAL sequences are case sensitive. Alignment has effect regardless of dialog variant and option (with exception to GUI based dialogs and Native (ASCII) mode as they strip newlines and multiple trailing/prefixing spaces). How the alignment is calculated:

     center_pad = (((width - 5) - length_of_line) / 2)
     right_pad  = ((width - 5) - length_of_line)
     left_pad   = 0

    5 is subracted from the width to account for the borders and gaps as these are included in the overall width of the displayed widget. All padding is made up of spaces appended to the beginning of the line. If the line length (before padding) is greater than the width (-5) then the width is increased to the length of the line (+5).

    All of these special text formatting sequences are stripped for gui based dialog variants as they do not support any such features. This includes the alignment specifications (even though they are not related to any one dialog variant).

REGARDING WIDGETS

    Most of these widgets are available across multiple variations of the dialog application.

     +--------------------------------------------+
     |              /Dialog_______________________|
     |              |   /cDialog__________________|
     |              |   |   /Whiptail_____________|
     |              |   |   |   /(g|k)Dialog______|
     |              |   |   |   |   /native_mode__|
     +--------------+   |   |   |   |   /---------+
     | widget       |   |   |   |   |   |         |
     +--------------+---+---+---+---+---+---------+
     | infobox      | X | X | X | X | X |         |
     | msgbox       | X | X | X | X | X |         |
     | textbox      | X | X | X | X | X |         |
     | yesno/noyes  | X | X | X | X | X |         |
     | inputbox     | X | X | X | X | X |         |
     | passwordbox  |   | X | X |   | X |         |
     | menu         | X | X | X | X | X |         |
     | radiolist    | X | X | X | X | X |         |
     | checklist    | X | X | X | X | X |         |
     | start_gauge  | X | X | X |N/A|   |         |
     | set_gauge    | X | X | X |/|\|   |         |
     | inc_gauge    | X | X | X | | |   |         |
     | dec_gauge    | X | X | X | | |   |         |
     | msg_gauge    | X | X |N/A|\|/|   |         |
     | end_gauge    | X | X | X |N/A|   |         |
     | tailbox      |   | X |   |   | X |         |
     | fselect      | * | X | * | * | * |         |
     | timebox      |   | X |   |   |   |         |
     | calendar     |   | X |   |   |   |         |
     +--------------+---+---+---+---+---+---------+

    N/A = Currently broken (either with this module or with the specific dialog variant).

    * = somewhat of a hack using the menu() widget to do some trickery with displaying directories. Any dialog but cDialog will use this and is unable to select a file that doesn't exist (which you can do with the cDialog variant).

    The following chart indicates the specific attributes used by the various widgets. Attributes listed in []'s are optional.

     +--------------+----------------------------+
     | widget       | Widget Specific Attributes |
     +--------------+----------------------------+
     | infobox      |   text                     |
     | msgbox       |   text                     |
     | textbox      |   file                     |
     | yesno        |   text                     |
     | inputbox     |   text, [init]             |
     | passwordbox  |   text, [init]             |
     | menu         |   text, menu               |
     | radiolist    |   text, list               |
     | checklist    |   text, list               |
     | start_guage  |   text, [percent]          |
     | tailbox      |   file                     |
     | fselect      |   path                     |
     | timebox      |   hour, minute, second     |
     | calendar     |   day, month, year         |
     +--------------+----------------------------+

    The 'menu' and 'list' attribute names can be used in any of the three widgets, but the values in the array must be correct. Here are the two styles:

     'menu' => [ 'tagname', 'description' ]
     'list' => [ 'tagname', 'description', 'state' ]
    
     'tagname' can be any string.
     'description' can be any string.
     'state' can be either 'on' or 'off'

    So these are valid:

     $d->menu({'list'=>['1','one','2','two']});
     $d->menu({'menu'=>['1','one','2','two']});
     $d->checklist({'menu'=>['1','one','off','2','two','off']});
     $d->checklist({'list'=>['1','one','off','2','two','off']});

    And this is silently invalid:

     $d->menu({'menu'=>['1','one','off','2','two','off']});

    And these are invalid with a msgbox displaying an error message:

     $d->menu({'list'=>['1','one','2','two','3']});
     $d->checklist({'menu'=>['1','one','ogg','2','two','3']});

    The only verification checks are for wether or not the menu lists are evenly divisible by 2 (for menu()) or 3 (for radiolist() or checklist()) and also for the radiolist() and checklist() widgets, every third element must be either 'on' or 'off' (case in-sensitive).

REGARDING NATIVE (ASCII) MODE

    This is probably the greatest feature of UDPM overall because not only is UDPM "dialog variant" independant, but having _any_ "dialog variant" is optional altogether. Native (ASCII) mode uses the fixed dimensions of 75 colums and 25 rows. In subsequent versions of UDPM there may be additional formats for all widgets (ie: "compact", "normal", "extended", or "custom").

    Be aware that the DELETE (or ^H) key may or may not work as expected when using ASCII mode. This is because input is handled by the simple "$input = <STDIN>;" statement. In later versions there will be a little more robust input handler implemented along with support for Readline (if already installed). Primarily the passwordbox() widget is affected by this limitation.

    NATIVE (ASCII) WIDGET NOTES

    textbox() and tailbox()

      textbox() uses either the environment variable or the runtime configuration variable 'pager' for displaying text files. Likewise, tailbox() uses the runtime configuration variable 'tail' and 'tailopt' to provide the widget's functionality.

    infobox() and msgbox()

      Both of these widgets simply print a simple template resembling the actual ncurses interfaces.

    inputbox() and passwordbox()

      Both of these widgets simply print the same standard ascii art used by infobox() and msgbox() except that at the bottom is a "input:" indicating the text input field.

      These three widgets allow for an unlimited number of menu entries. Note that any default selections (indicated by '->') on the radiolist() and checklist() widgets are not used for anything practical aside from suggesting the end-user to notice those item(s).

      On the bottom left of the screen you'll notice a page indicator:

       (n/m) :
      
       'n' = current page
       'm' = total number of pages

      Each page currently has room for 30 menu entries. This number is hard-coded and un-alterable (this may change with the "custom" print formats sometime in the future).

      To navigate the menus use:

       +--------------+---------------------------+
       | string       | action                    |
       +--------------+---------------------------+
       | :?           | This help message         |
       | :h :help     | Press the [Help] button   |
       | :e :extra    | Press the [Extra] button  |
       | :esc :escape | Press the [Esc] button    |
       | :c :cancel   | Press the [Cancel] button |
       | :pg <N>      | Go to page 'N'            |
       | :n :next     | Go to the next page       |
       | :p :prev     | Go to the previous page   |
       +--------------+---------------------------+

      At the bottom of every menu(), radiolist() or checklist() are two lines:

         ':e'=[Extra]    ':c'=[Cancel]      ':h'=[Help]
                  ':?'=[Colon Command Help]

      The Extra, Cancel and Help are actually the widget buttons and may or may not be visible depending on the runtime configuration (ie: 'extra-button'=>'1' will make the Extra button visible). This runtime configuration also enables/disables these three widget buttons. The Colon Command Help is always visible and always functional where as the other widget buttons are configuration dependant for functionality.

BONUS FEATURES

    These features are in some way related to interfacing with the end-user (and/or end-user's environment).

NAUTILUS SCRIPT SUPPORT

nautilus_paths()

EXAMPLE
     my @paths = $d->nautilus_paths();
     foreach my $file (@paths) {
       ...
     }
DESCRIPTION

    This method returns an array containing all the selected files in standard unix path format.

nautilus_path()

EXAMPLE
     my $path = $d->nautilus_path();
     chdir($path);
DESCRIPTION

    This method returns a single string containing the standard unix path of the selected item's parent directory. This is derived from the nautilus_uri() method and is simply stripped of the "file://".

nautilus_uris()

EXAMPLE
     my @uris = $d->nautilus_uris();
     foreach my $uri (@uris) {
       ...
     }
DESCRIPTION

    This method returns an array containing all the selected items in standard URI format.

nautilus_uri()

EXAMPLE
     my $uri = $d->nautilus_uri();
     $uri =~ s/^file:\/\/(.*)$/$1/;
     chdir($uri);
DESCRIPTION

    This method returns a single string containing the URI of the selected item's parent directory.

nautilus_geometry()

EXAMPLE
     my ($w,$h,$x,$y) = $d->nautilus_geometry();
DESCRIPTION

    This method returns four values; in order:

     width
     height
     x
     y

nautilus_debug()

EXAMPLE
     $d->nautilus_debug();
DESCRIPTION

    This method simply runs a msgbox() with all the nautilus data displayed. When using this, be sure to enforce the use of a gui dialog variant. This is of most use when first learning to use UDPM for nautilus scripts. Here is a "classic" nautilus debugging script (save and `chmod 0755` this to something like: ~/.gnome2/nautilus-scripts/nautilus_debug):

     #!/usr/bin/perl
     use strict;
     use warnings;
     use diagnostics;
     use UDPM;
    
     chomp(my $DIALOG = `/usr/bin/which gdialog`);
     if (!-x $DIALOG) {
       chomp($DIALOG = `/usr/bin/which kdialog`);
       if (!-x $DIALOG) {
         print STDERR "Couldn't find a suitable gui based dialog variant\n";
         exit(1);
       }
     }
    
     my $d = new UDPM ({'dialogbin'=>$DIALOG});
     $d->nautilus_debug();
    
     exit(0);

FINAL NOTES

    This module will NOT run in TAINT mode at all. I don't see how this could even be possible (without circumventing the whole purpose of TAINT mode). This isn't to say that the author of UDPM won't take any suggestions on how to usefully implement a "taint" mode within UDPM.

    If you plan on utilizing this module in any "mission critical" situations be forwarned that there are probably many ways a malicious cracker could break the system.

    UDPM was designed and built using Debian (Unstable), Perl 5.8.0, Dialog 0.9b, Whiptail 0.50.17, GDialog 2.0.6, and Bash 2.05b.

    UDPM has implemented both Linux and BSD functionality for certain widgets in native ascii mode and the BSD aspects have never been tested. Running the included example Perl script (udpm-demo.pl) on a BSD system in native ascii mode would highlight any imperfections. Specifically, the platform specific instructions are 'stty' commands and as such these differ between Linux and BSD. The platform specific code came from `perldoc -f getc` and pertains primarily to the passwordbox() widget.

SEE ALSO

    Unix man pages:

     dialog(1), whiptail(1), gdialog(1), kdialog(1) and nautilus(1)

    Mailing list:

     http://lists.sourceforge.net/mailman/listinfo/udpm-list

    Official project site:

     http://udpm.sourceforge.net

AUTHOR

Kevin C. Krinke, <kckrinke@opendoorsoftware.com>

COPYRIGHT AND LICENSE

 Copyright (C) 2002  Kevin C. Krinke <kckrinke@opendoorsoftware.com>

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

85 POD Errors

The following errors were encountered while parsing the POD:

Around line 2234:

You forgot a '=back' before '=head2'

Around line 2260:

=back without =over

Around line 2264:

You forgot a '=back' before '=head2'

Around line 2290:

=back without =over

Around line 2294:

You forgot a '=back' before '=head2'

Around line 2317:

=back without =over

Around line 2321:

You forgot a '=back' before '=head2'

Around line 2346:

=back without =over

Around line 2350:

You forgot a '=back' before '=head2'

Around line 2375:

=back without =over

Around line 2379:

You forgot a '=back' before '=head2'

Around line 2409:

=back without =over

Around line 2413:

You forgot a '=back' before '=head2'

Around line 2437:

=back without =over

Around line 2441:

You forgot a '=back' before '=head2'

Around line 2463:

=back without =over

Around line 2467:

You forgot a '=back' before '=head2'

Around line 2489:

=back without =over

Around line 2493:

You forgot a '=back' before '=head2'

Around line 2518:

=back without =over

Around line 2522:

You forgot a '=back' before '=head2'

Around line 2545:

=back without =over

Around line 2549:

You forgot a '=back' before '=head2'

Around line 2572:

=back without =over

Around line 2576:

You forgot a '=back' before '=head2'

Around line 2599:

=back without =over

Around line 2603:

You forgot a '=back' before '=head2'

Around line 2626:

=back without =over

Around line 2630:

You forgot a '=back' before '=head2'

Around line 2653:

=back without =over

Around line 2659:

You forgot a '=back' before '=head2'

Around line 2682:

=back without =over

Around line 2686:

You forgot a '=back' before '=head2'

Around line 2717:

=back without =over

Around line 2721:

You forgot a '=back' before '=head2'

Around line 2743:

=back without =over

Around line 2747:

You forgot a '=back' before '=head2'

Around line 2770:

=back without =over

Around line 2774:

You forgot a '=back' before '=head2'

Around line 2803:

=back without =over

Around line 2807:

You forgot a '=back' before '=head2'

Around line 2838:

=back without =over

Around line 2842:

You forgot a '=back' before '=head2'

Around line 2865:

=back without =over

Around line 2869:

You forgot a '=back' before '=head2'

Around line 2893:

=back without =over

Around line 2897:

You forgot a '=back' before '=head2'

Around line 2925:

=back without =over

Around line 2929:

You forgot a '=back' before '=head2'

Around line 2960:

=back without =over

Around line 2964:

You forgot a '=back' before '=head2'

Around line 2995:

=back without =over

Around line 2999:

You forgot a '=back' before '=head2'

Around line 3025:

=back without =over

Around line 3029:

You forgot a '=back' before '=head2'

Around line 3053:

=back without =over

Around line 3057:

You forgot a '=back' before '=head2'

Around line 3081:

=back without =over

Around line 3085:

You forgot a '=back' before '=head2'

Around line 3109:

=back without =over

Around line 3113:

You forgot a '=back' before '=head2'

Around line 3136:

=back without =over

Around line 3140:

You forgot a '=back' before '=head2'

Around line 3166:

=back without =over

Around line 3170:

You forgot a '=back' before '=head2'

Around line 3193:

=back without =over

Around line 3197:

You forgot a '=back' before '=head2'

Around line 3226:

=back without =over

Around line 3230:

You forgot a '=back' before '=head2'

Around line 3259:

=back without =over

Around line 3263:

You forgot a '=back' before '=head2'

Around line 3297:

=back without =over

Around line 3812:

You can't have =items (as at line 3828) unless the first thing after the =over is an =item

Around line 3930:

You forgot a '=back' before '=head2'

Around line 3956:

=back without =over

Around line 3960:

You forgot a '=back' before '=head2'

Around line 3985:

=back without =over

Around line 3989:

You forgot a '=back' before '=head2'

Around line 4015:

=back without =over

Around line 4019:

You forgot a '=back' before '=head2'

Around line 4044:

=back without =over

Around line 4048:

You forgot a '=back' before '=head2'

Around line 4075:

=back without =over

Around line 4079:

You forgot a '=back' before '=head2'

Around line 4126:

=back without =over