--- Slim.orig/Music/Info.pm 2005-01-10 13:14:59.000000000 +0000 +++ Slim/Music/Info.pm 2005-01-17 14:49:37.988443984 +0000 @@ -155,6 +155,46 @@ ,'mpc' => \&Slim::Formats::Musepack::getTag ); +# Hash containing replacements for lazy multi-tap searching. Anything not in +# here will just be translated to itself as we don't have any better idea. See +# the lazyMultiTapDecode function for further details of how this works. +my %lazyMultiTapMap = ( + 'A' => 'A', + 'B' => 'AA', + 'C' => 'AAA', + '2' => 'AAAA', + 'D' => 'D', + 'E' => 'DD', + 'F' => 'DDD', + '3' => 'DDDD', + 'G' => 'G', + 'H' => 'GG', + 'I' => 'GGG', + '4' => 'GGGG', + 'J' => 'J', + 'K' => 'JJ', + 'L' => 'JJJ', + '5' => 'JJJJ', + 'M' => 'M', + 'N' => 'MM', + 'O' => 'MMM', + '6' => 'MMMM', + 'P' => 'P', + 'Q' => 'PP', + 'R' => 'PPP', + 'S' => 'PPPP', + '7' => 'PPPPP', + 'T' => 'T', + 'U' => 'TT', + 'V' => 'TTT', + '8' => 'TTTT', + 'W' => 'W', + 'X' => 'WW', + 'Y' => 'WWW', + 'Z' => 'WWWW', + '9' => 'WWWWW' +); + # if we don't have storable, then stub out the cache routines if (defined @Storable::EXPORT) { @@ -1560,7 +1600,10 @@ if ($const eq '') { ITEM: foreach my $item (@items) { foreach my $regexpattern (@{$patterns}) { - if ($item !~ $regexpattern) { + my $lazyitem = lazyEncode($item); + my $lazyregexpattern = lazyMultiTapDecode($regexpattern); + if (($item !~ $regexpattern) && + ($lazyitem !~ $lazyregexpattern)) { next ITEM; } } @@ -1569,8 +1612,11 @@ } else { ITEM: foreach my $item (@items) { my $item_const = $item . ' ' . $const; + my $lazyitem_const = lazyEncode($item_const); foreach my $regexpattern (@{$patterns}) { - if ($item_const !~ $regexpattern) { + my $lazyregexpattern = lazyMultiTapDecode($regexpattern); + if (($item_const !~ $regexpattern) && + ($lazyitem_const !~ $lazyregexpattern)) { next ITEM; } } @@ -1595,8 +1641,10 @@ my @filtereditems; my ($k,$v); ENTRY: while (($k,$v) = each %{$hashref}) { + my $lazyv = lazyEncode($v); foreach my $pat (@{$patterns}) { - if ($v !~ $pat) { + my $lazypat = lazyMultiTapDecode($pat); + if (($v !~ $pat) && ($lazyv !~ $lazypat)) { next ENTRY; } } @@ -2920,6 +2968,48 @@ return $type; } +# Convert a string to a lazy-entry encoded string. We store this in the +# cache so that we can then search for it quickly later. +# +# called: +# undef +sub lazyEncode { + my $string = shift; + # This translates each searchable character into the first character that + # appears on that key on the remote. Thus, this gives you what the user + # will enter if he doesn't bother to multi-tap to get at the later + # characters. + # We do all this on an upper case version, since upper case is all the user + # can enter through the remote control. + $string = uc $string; + $string =~ tr/ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 /AAADDDGGGJJJMMMPPPPTTTWWWW.ADGJMPTW /; + return $string; +} + +# Allow the user to put in lazy searches when adjacent characters are on the +# same key without having to press right arrow or wait a while. It does this by +# translating non-first keys into the right number of initial character +# alternatives. +# Decoding "PTNDP" ("STONES") should become "PTMMDP" +# and "ODW" ("MONEY") should become "MMMDW". +# +# called: +# undef +sub lazyMultiTapDecode { + my $in_string = shift; + my $out_string = ""; + + # Loop through all the characters (back-to-front), and build up an + # output string with the appropriate replacements. + while ($in_string) { + my $in_c = chop $in_string; + my $out_c = $lazyMultiTapMap{$in_c}; + $out_c = $in_c unless $out_c; + $out_string = $out_c . $out_string; + } + + return $out_string; +} 1; __END__