The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Tk::MatchEntry - Entry widget with advanced auto-completion capability

SYNOPSIS

 use Tk::MatchEntry;

 $match_entry = $top->MatchEntry(-textvariable => \$var1, 
                                 -choices => @choices);

DESCRIPTION

Tk::MatchEntry is an Entry widget with focus on user-friendly auto-completion. Its usage is similar to Tk::BrowseEntry and Tk::HistEntry.

With each character the user types in the widget, automatic completion can be attempted based on a list of choices you as programmer specify.

If there's more than one of the choices matching the text which the user has entered so far, she can optionally select the desired auto-completion choice from an up-popping listbox, either by using the mouse or by browsing them with the Up and Down cursor keys.

This listbox with auto-completion choices pops up automatically by default and only shows these choices which still can match the manually entered text, i.e. the number of displayed items usually decreases with the length of text entered by the user.

The auto-completed part of the text in the Entry widget always gets selected so the next manually entered character overwrites it. Thus, the auto-completion feature never prevents the user from typing what she really wants to.

Starting with version 0.2, Tk::MatchEntry has a multi-match mode in which each word the user types can be auto-completed. For example, if you've got the four choices Another, Hacker, Just and Perl, the user can write Just Another Perl Hacker for example by hitting J, Return, A, Return, P, Return, H, Return.

OPTIONS

Besides the options which can be applied to the entry and slistbox subwidgets, MatchEntry provides the following specific options:

-textvariable or -variable

The variable which is tied to the MatchEntry widget. -variable, as used in BrowseEntry, is just an alias for -textvariable. This variable will contain the entry widget's text.

-choices

Array of strings which the auto-completion feature attempts to match. Used the same way as in Tk::BrowseEntry.

-complete

If set to a true value, auto-completion is attempted whenever the user enters another character in the widget. This is what Tk::MatchEntry is all about, so it defaults to 1. Auto-completion is hopefully smart enough to know what the user wants to do and doesn't mess up the text she's entering.

-ignorecase

If not false, auto-completion works case-insensitive. Thus, if you have a choice John Doe and the user starts with a j, auto-completion will be john Doe. However, if auto-completion is set to case-insensitivity AND the text in the entry widget matches one of the choices when the MatchEntry widget is left, the text will be replaced by the choice, i.e. in our example, john Doe would turn into John Doe. Defaults to 0.

-autopopup

If set to a true value, the listbox with auto-completion choices will automatically pop up if the user has entered at least one character in the widget yet AND there's at least two possible choices. Defaults to 1.

-maxheight

Sets the maximum number of entries per page in the (scrolled) popup listbox with auto-completion choices. Defaults to 5.

-autoshrink

If set to a true value, the popup listbox's height will decrease if there's less than -maxheight items to display. For example, if -maxheight is set to 5, but there's only 3 choices, and -autoshrink is set to 1, then the listbox will show only those 3 choices instead of the 3 choices plus two empty rows.

-fixedwidth

If set to a true value, the popup listbox will always have the same width as the entry widget. Otherwise, the width of the listbox is calculated the same way as in Tk::BrowseEntry. Defaults to 1.

-listwidth

If -fixedwidth is set to 0, -listwidth can be used to specify the popup listbox's width.

-multimatch

When set to a true value, the multi-match mode is activated. In regular mode, Tk::MatchEntry attempts to match and auto-complete the whole text in the entry widget. In multi-match mode, it does the same for each word the user enters. Don't use this unless you're sure that's what you want. When using multi-match mode, the choices should be single words (as opposed to phrases, i.e. multiple blank-separated words). Defaults to 0.

-autosort

When set to a true value, the choices are automatically sorted, either when set through -choices in the new method or through the choices method. Sorting is done with Perl's built-in sort function unless you've specified a -sortcmd callback. Defaults to 1.

-sorttrigger

Useful in multi-match mode when using a custom -sortcmd callback which sorts the choices based on what the user has entered so far. -sorttrigger is a regular expression; if it matches against the user's latest pressed key, then the resort method is called. The -sortcmd callback can then be used to add words entered by the user to the list of choices, sort them by usage frequency, etc.

The value of this option defaults to undef and you should only change it if you know what you're doing: both matching this regular expression against each key pressed by the user and unnecessarily often calling resort can decrease performance.

Example usage:

 ...
 -sorttrigger => '^Left|^Right|^space|^Home|^End',
 ...
 

(The lower case s in ^space is actually not a typo)

-matchprefix

Using a match prefix allows lazy typing on your user's side. It's best explained by comparing it to the field where you enter a URL in modern web browsers. Let's say you have a choice

 http://www.cpan.org

and you would like to allow the user typing either of these:

 http://www.cpan.org
 www.cpan.org
 cpan.org

while still getting the benefits of auto-completion and the up-popping choices listbox, then you should set -matchprefix to

 '(?:http:\/\/)?(?:www\.)?'

In fact, -matchprefix is a regular expression which must fulfill the following criteria:

1) You must use non-capturing brackets if you're using grouping. That's why we use

 (?:http:\/\/)?

in the above example and NOT

 (http:\/\/)?

2) Prefix matches must be optional, i.e. you always should use the ? quantifier (using * would work, too, but might be bad for performance).

Here's another example for matching HTTP and FTP URLs like in the above example, i.e. both the http:// and www. parts are optional.

 ...
 -matchprefix => '(?:(?:ftp|http):\/\/)?(?:(?:ftp|www)\.)?',
 ...
-wraparound

If set to a true value, then the selection in the popup listbox will wrap around to the first entry if the user presses the down cursor key at the very bottom of the listbox. Also, the last entry in the listbox will be selected after pressing cursor-up while having the first listbox entry selected. Defaults to 0.

The following options specify callbacks:

-listcmd

Executed when the listbox is about to be popped up. This is a good place for changes to the -choices.

-entercmd

Executed when the user hits the Return key.

-tabcmd

Executed when the user hits the Tab key.

-zerocmd

Executed when the insert cursor moves back to position 0 in the entry widget (see -onecmd).

-onecmd

Executed when the insert cursor moves to position 1 in the entry widget (i.e. after the first character).

-zerocmd and -onecmd are supposed to be used together in applications where you want totally different choices depending on whether the user has already entered any text yet. For example, if a MatchEntry widget is used for the recipient's name in an email client, the choices

a) when the user has not entered anything yet could be the names of the 10 last persons he had sent an email to.

b) after entering the first character could be appropriate names from his address book.

-command or -browsecmd

Executed when the user has selected an entry from the auto-completion popup-listbox. Provided for compatibility with Tk::BrowseEntry.

-mm_zerocmd and -mm_onecmd

Same as -zerocmd and -onecmd, additionally called in multimatch mode if the current word's length is 0, or 1 respectively.

-sortcmd

Callback used to sort the array of choices. If you don't specify this callback, Perl's internal sort function will be used to sort the choices alphabetically unless autosort is turned off.

A reference to the array of choices is passed to the custom sorting function and it must return a reference to the sorted array.

Trivial example:

 sub mysort {
     my $ref = shift;
     my @choices = @$ref;
     my @sorted_choices = sort @choices;
     return \@sorted_choices;
 }

You can abuse this callback to insert or delete choices while sorting them. Normally, the standard choices method is used to update the choices array, of course.

-bottomcmd

Called when the user presses the cursor-down key if the bottom entry in the popup listbox was already selected. Can be used for accoustic signals etc. Called even if -wraparound is true.

-topcmd

Same as -bottomcmd but called when the user presses the cursor-up key if already at the first entry of the popup listbox.

METHODS

Pops the auto-completion listbox up if there are enough possible choices. This should only be used if -autopopup is set to 0. As Tk::MatchEntry does, compared to Tk::BrowseEntry and Tk::HistEntry, not provide an arrow button for popping up the listbox, you might want to use a button of your own for this purpose.

If the listbox is already open, calling this method closes it.

choices

If called with no parameter, this returns an array containing the current choices.

If given an array as parameter, it will set the choices. Unless autosort is turned off, the choices will be sorted automatically, either using Perl's built-in sort function or the -sortcmd callback you've specified.

resort

Enforces re-sorting the array of choices, either using Perl's built-in sort function or the -sortcmd callback if you've specified one. Useful if autosort is turned off or your custom -sortcmd wants to take into account what the user has entered so far, for instance to sort the choices by their usage frequency in multi-match mode.

KEY BINDINGS

Up, Down

Navigates through the auto-completion listbox. Forces the listbox to pop up when used at entry widget cursor position 0 if there are any choices to display.

Tab, Return

Accepts the currently suggested or selected auto-completion. The insert cursor will be placed at the end of the entry widget. The callback -tabcmd or -entercmd will be executed.

Escape

Pressed once it closes the auto-completion listbox if it's open. On pressing it twice the currently auto-completed text will be erased. For example, if you have a choice John Doe, but the user just wants to enter John, she actually has to press Escape (or Delete) to remove the auto-completed Doe part.

NOTES

If you need to configure the subwidgets, for example to set different background colors for the entry and the listbox widget, you can access them like this:

 my $entry_subwidget = $matchentry->Subwidget('entry');

 my $listbox_subwidget = 
    $matchentry->Subwidget('slistbox')->Subwidget('listbox');

slistbox is the scrolled listbox.

BUGS

Execution of the -browsecmd callback needs improvement.

EXAMPLES

This is a primitive example for Tk::MatchEntry which you can use to get to know the look and feel.

 use Tk;

 use Tk::MatchEntry;

 my $mw = MainWindow->new(-title => "MatchEntry Test");

 my @choices = [ qw/one one.green one.blue one.yellow two.blue two.green
                    two.cyan three.red three.white three.yellow/ ];

 $mw->Button->pack(-side => 'left');

 my $me = $mw->MatchEntry(
        -choices        => @choices,
        -fixedwidth     => 1, 
        -ignorecase     => 1,
        -maxheight      => 5,
        -entercmd       => sub { print "callback: -entercmd\n"; }, 
        -onecmd         => sub { print "callback: -onecmd  \n"; }, 
        -tabcmd         => sub { print "callback: -tabcmd  \n"; }, 
        -zerocmd        => sub { print "callback: -zerocmd \n"; },
    )->pack(-side => 'left', -padx => 50);

 $mw->Button(-text => 'popup', 
             -command => sub{$me->popup}
            )->pack(-side => 'left');
 
 MainLoop;

AUTHOR

Wolfgang Hommel <wolf (at) code-wizards.com>

SEE ALSO

The following widgets are similar to Tk::MatchEntry to a certain extent:

Tk::BrowseEntry
Tk::HistEntry
Tk::JBrowseEntry
Tk::SelectionEntry

CREDITS

Thanks to

Slaven Rezic for Tk::HistEntry. Some of the auto-completion ideas are based on it.
Jesse Farinacci for suggesting, specifying and testing the multimatch mode.
Ingo Herschmann for bug reports and patches.

COPYRIGHT

Copyright (c) 2003 - 2005 Wolfgang Hommel. All rights reserved.

This package is free software; you can redistribute it and/or modifiy it under the same terms as Perl itself.