Index: Slim/Plugin/Favorites/HTML/EN/plugins/Favorites/index.html =================================================================== --- Slim/Plugin/Favorites/HTML/EN/plugins/Favorites/index.html (revision 17848) +++ Slim/Plugin/Favorites/HTML/EN/plugins/Favorites/index.html (working copy) @@ -110,7 +110,7 @@ [% BLOCK entryblock -%] [%- WRAPPER contentitem leftcontrols = 'playcontrols' rightcontrols = 'editcontrols' itemobj.id = entry.index %] - [% entry.title %] + [% entry.title %][% IF entry.hotkey.defined %] [ [% entry.hotkey %] ] [% END %] [% END -%] [% END %] Index: Slim/Plugin/Favorites/OpmlFavorites.pm =================================================================== --- Slim/Plugin/Favorites/OpmlFavorites.pm (revision 17688) +++ Slim/Plugin/Favorites/OpmlFavorites.pm (working copy) @@ -76,7 +76,9 @@ my $index = shift || ''; unless (defined $level) { - $class->{'urlindex'} = {}; + $class->{'url-index'} = {}; + $class->{'hotkey-index'} = {}; + $class->{'url-hotkey'} = {}; $level = $class->toplevel; } @@ -85,9 +87,14 @@ for my $entry (@{$level}) { if ($entry->{'URL'} || $entry->{'url'}) { - $class->{'urlindex'}->{ $entry->{'URL'} || $entry->{'url'} } = $index . $i; + $class->{'url-index'}->{ $entry->{'URL'} || $entry->{'url'} } = $index . $i; } + if (defined $entry->{'hotkey'}) { + $class->{'hotkey-index'}->{ $entry->{'hotkey'} } = $index . $i; + $class->{'url-hotkey'}->{ $entry->{'URL'} || $entry->{'url'} } = $entry->{'hotkey'}; + } + if ($entry->{'outline'}) { $class->_urlindex($entry->{'outline'}, $index."$i."); } @@ -105,14 +112,21 @@ my @urls = @{Slim::Utils::Prefs::OldPrefs->get('favorite_urls') || []}; my @titles = @{Slim::Utils::Prefs::OldPrefs->get('favorite_titles') || []} ; + my @hotkeys= (1..9, 0); while (@urls) { - push @$toplevel, { - 'text' => shift @titles, - 'URL' => shift @urls, - 'type' => 'audio', + my $entry = { + 'text' => shift @titles, + 'URL' => shift @urls, + 'type' => 'audio', }; + + if (@hotkeys) { + $entry->{'hotkey'} = shift @hotkeys; + } + + push @$toplevel, $entry; } $class->title(string('FAVORITES')); @@ -136,6 +150,7 @@ my $title = shift; my $type = shift; my $parser = shift; + my $hotkey = shift; if (!$url) { logWarning("No url passed! Skipping."); @@ -149,7 +164,7 @@ $url =~ s/\?sessionid.+//i; # Bug 3362, ignore sessionID's within URLs (Live365) if ( $log->is_info ) { - $log->info(sprintf("url: %s title: %s type: %s parser: %s", $url, $title, $type, $parser)); + $log->info(sprintf("url: %s title: %s type: %s parser: %s hotkey: %s", $url, $title, $type, $parser, $hotkey)); } # if its already a favorite, don't add it again @@ -171,19 +186,28 @@ delete $entry->{'type'}; } + if ($hotkey) { + for my $i (1..9, 0) { + if (!defined $class->{'hotkey-index'}->{ $i }) { + $entry->{'hotkey'} = $i; + last; + } + } + } + # add it to end of top level push @{$class->toplevel}, $entry; $class->save; - return scalar @{$class->toplevel} - 1; + return wantarray ? (scalar @{$class->toplevel} - 1, $entry->{'hotkey'}) : scalar @{$class->toplevel} - 1; } sub hasUrl { my $class = shift; my $url = shift; - return (defined $class->{'urlindex'}->{ $url }); + return (defined $class->{'url-index'}->{ $url }); } sub findUrl { @@ -192,13 +216,14 @@ $url =~ s/\?sessionid.+//i; # Bug 3362, ignore sessionID's within URLs (Live365) - my $index = $class->{'urlindex'}->{ $url }; + my $index = $class->{'url-index'}->{ $url }; + my $hotkey = $class->{'url-hotkey'}->{ $url }; if (defined $index) { $log->info("Match $url at index $index"); - return $index; + return wantarray ? ($index, $hotkey) : $index; } $log->info("No match for $url"); @@ -216,9 +241,9 @@ $url =~ s/\?sessionid.+//i; # Bug 3362, ignore sessionID's within URLs (Live365) - if (exists $class->{'urlindex'}->{ $url }) { + if (exists $class->{'url-index'}->{ $url }) { - $class->deleteIndex($class->{'urlindex'}->{ $url }); + $class->deleteIndex($class->{'url-index'}->{ $url }); } else { @@ -242,5 +267,49 @@ } } +sub hotkeys { + my $class = shift; + return keys %{$class->{'hotkey-index'}}; +} + +sub hasHotkey { + my $class = shift; + my $key = shift; + + return $class->{'hotkey-index'}->{ $key }; +} + +sub setHotkey { + my $class = shift; + my $index = shift; + my $key = shift; + + if (defined $key && $class->{'hotkey-index'}->{ $key }) { + + $log->warn("Hotkey $key already used - not setting"); + return; + } + + my ($pos, $i) = $class->level($index, 'contains'); + + if (ref @{$pos}[ $i ] eq 'HASH') { + + if (defined $key) { + + @{$pos}[ $i ]->{'hotkey'} = $key; + + $log->info("Setting hotkey $key for index $index"); + + } else { + + delete @{$pos}[ $i ]->{'hotkey'}; + + $log->info("Deleting hotkey for index $index"); + } + + $class->save; + } +} + 1; Index: Slim/Plugin/Favorites/Plugin.pm =================================================================== --- Slim/Plugin/Favorites/Plugin.pm (revision 17657) +++ Slim/Plugin/Favorites/Plugin.pm (working copy) @@ -38,6 +38,10 @@ my $prefs = preferences('plugin.favorites'); +# support multiple edditing sessions at once - indexed by sessionId. [Default to favorites editting] +my $nextSession = 2; # session id 1 = favorites +tie my %sessions, 'Tie::Cache::LRU', 4; + sub initPlugin { my $class = shift; @@ -63,10 +67,11 @@ # register notifications Slim::Control::Request::addDispatch(['favorites', 'changed'], [0, 0, 0, undef]); - # register new mode for deletion of favorites + # register new modes for deleting favorites Slim::Buttons::Common::addMode( 'favorites.delete', {}, \&deleteMode ); } + sub modeName { 'FAVORITES' }; sub setMode { @@ -103,11 +108,12 @@ my $title = $client->modeParam('title'); # title to display my $index = $client->modeParam('index'); # favorite index to delete + my $hotkey= $client->modeParam('hotkey');# favorite hotkey my $depth = $client->modeParam('depth'); # number of levels to pop out of when done # Bug 6177, Menu to confirm favorite removal Slim::Buttons::Common::pushMode( $client, 'INPUT.Choice', { - header => '{FAVORITES_FAVORITE} ' . ($index + 1), + header => '{FAVORITES_FAVORITE} ' . (defined $hotkey ? $hotkey : ''), title => $title, favorite => $index, listRef => [ @@ -156,8 +162,9 @@ my $button = shift; my $digit = shift; - # we need to deal with $digit being 1-9 or 0 meaning 10 and convert to zero based index - my $entry = Slim::Plugin::Favorites::OpmlFavorites->new($client)->entry($digit != 0 ? $digit - 1 : 9); + my $favs = Slim::Plugin::Favorites::OpmlFavorites->new($client); + my $index = $favs->hasHotkey($digit); + my $entry = defined $index ? $favs->entry($index) : undef; if (defined $entry && $entry->{'type'} && $entry->{'type'} eq 'audio') { @@ -177,7 +184,7 @@ $log->info("Can't play favorite number $digit - not an audio entry"); $client->showBriefly({ - 'line' => [ sprintf($client->string('FAVORITES_NOT_DEFINED'), $digit != 0 ? $digit : 10) ], + 'line' => [ sprintf($client->string('FAVORITES_NOT_DEFINED'), $digit) ], }); } } @@ -199,10 +206,6 @@ Slim::Web::Pages->addPageLinks('plugins', { 'PLUGIN_FAVORITES_PLAYLIST_EDITOR' => $enabled ? 'plugins/Favorites/index.html?new' : undef }); } -# support multiple edditing sessions at once - indexed by sessionId. [Default to favorites editting] -my $nextSession = 2; # session id 1 = favorites -tie my %sessions, 'Tie::Cache::LRU', 4; - sub toggleButtonHandler { my $client = shift; my $params = shift; @@ -527,6 +530,11 @@ $favs->deleteUrl( $entry->{'URL'} ); } + + if ($action eq 'hotkey' && defined $params->{'index'} && $opml->isa('Slim::Plugin::Favorites::OpmlFavorites')) { + + $opml->setHotkey( $params->{'index'}, $params->{'hotkey'} ne '' ? $params->{'hotkey'} : undef ); + } } if ($params->{'forgetdelete'}) { @@ -611,6 +619,10 @@ $entry->{'favorites'} = $favs->hasUrl($entry->{'url'}) ? 2 : 1; } + if (!$favs && defined $opmlEntry->{'hotkey'}) { + $entry->{'hotkey'} = $opmlEntry->{'hotkey'}; + } + push @entries, $entry; } @@ -618,6 +630,11 @@ $params->{'levelindex'} = join '.', @indexPrefix; $params->{'indexOnLevel'} = $indexLevel; + # for favorites add the currently used hotkeys + if (!$favs) { + $params->{'hotkeys'} = $opml->hotkeys; + } + # add the top level title to pwd_list push @{$params->{'pwd_list'}}, { 'title' => $opml && $opml->title || string('PLUGIN_FAVORITES_EDITOR'), @@ -743,8 +760,11 @@ } if (defined $i) { + splice @$level, $i, 0, $entry; + } else { # with no specific index, place automatically at the end + push @$level, $entry; } @@ -754,15 +774,13 @@ if ($request->source && $request->source =~ /\/slim\/request/) { $client->showBriefly({ 'jive' => { - 'text' => [ Slim::Utils::Strings::string('FAVORITES_ADDING'), - $title, - ], + 'text' => [ Slim::Utils::Strings::string('FAVORITES_ADDING'), + $title, + ], } }); - } - $request->setStatusDone(); } else { @@ -806,7 +824,6 @@ }); } - $request->setStatusDone(); } Index: Slim/Buttons/BrowseDB.pm =================================================================== --- Slim/Buttons/BrowseDB.pm (revision 17688) +++ Slim/Buttons/BrowseDB.pm (working copy) @@ -403,6 +403,7 @@ my $favorites = Slim::Utils::Favorites->new($client); my $index = $client->modeParam('favorite'); + my $hotkey = $client->modeParam('hotkey'); my $track = Slim::Schema->find('Track', $client->modeParam('findCriteria')->{'playlist.id'}); if (!blessed($track) || !$track->can('title')) { @@ -418,13 +419,14 @@ if ( !defined $index ) { - $index = $favorites->add($track, $track->title); + ($index, $hotkey) = $favorites->add($track, $track->title, undef, undef, 'hotkey'); $client->showBriefly( { 'line' => [ $client->string('FAVORITES_ADDING'), $track->title ] }); $client->modeParam('favorite', $index); + $client->modeParam('hotkey', $hotkey); } else { @@ -432,6 +434,7 @@ Slim::Buttons::Common::pushModeLeft( $client, 'favorites.delete', { title => $track->title, index => $index, + hotkey=> $hotkey, depth => 2, } ); @@ -521,15 +524,10 @@ if (!$blessed && $item eq 'FAVORITE') { my $index = $client->modeParam('favorite'); + my $hotkey = $client->modeParam('hotkey'); if (defined $index) { - if ($index =~ /^\d+$/) { - # existing favorite at top level - display favorite number starting at 1 (favs are zero based) - return $client->string('FAVORITES_FAVORITE') . ' ' . ($index + 1); - } else { - # existing favorite not at top level - don't display number - return $client->string('FAVORITES_FAVORITE'); - } + return $client->string('FAVORITES_FAVORITE') . (defined $hotkey ? ' ' . $hotkey : ''); } else { $item = $client->string('FAVORITES_RIGHT_TO_ADD'); } @@ -813,8 +811,11 @@ if (blessed($track) && $track->can('id')) { - $client->modeParam('favorite', Slim::Utils::Favorites->new($client)->findUrl($track->url) ); + my ($index, $hotkey) = Slim::Utils::Favorites->new($client)->findUrl($track->url); + $client->modeParam('favorite', $index); + $client->modeParam('hotkey', $hotkey); + push @items, 'FAVORITE'; } } @@ -877,6 +878,7 @@ findCriteria => $filters, selectionCriteria => $selectionCriteria, favorite => $client->modeParam('favorite'), + hotkey => $client->modeParam('hotkey'), ); # If this is a list of containers (e.g. albums, artists, genres) Index: Slim/Buttons/TrackInfo.pm =================================================================== --- Slim/Buttons/TrackInfo.pm (revision 17688) +++ Slim/Buttons/TrackInfo.pm (working copy) @@ -196,6 +196,7 @@ 'track' => $client->modeParam('track'), 'current' => $client->modeParam('current'), 'favorite' => $client->modeParam('favorite'), + 'hotkey' => $client->modeParam('hotkey'), ); Slim::Buttons::Common::pushMode($client, 'INPUT.List', \%params); @@ -384,8 +385,11 @@ if (Slim::Music::Info::isURL($track->url) && Slim::Utils::Favorites->enabled) { - $client->modeParam( 'favorite', Slim::Utils::Favorites->new($client)->findUrl($track->url) ); + my ($index, $hotkey) = Slim::Utils::Favorites->new($client)->findUrl($track->url); + $client->modeParam('favorite', $index); + $client->modeParam('hotkey', $hotkey); + push (@{$client->trackInfoLines}, 'FAVORITE'); # replaced in lines() push (@{$client->trackInfoContent}, { 'type' => 'FAVORITE', @@ -510,16 +514,18 @@ my $favorites = Slim::Utils::Favorites->new($client); my $favIndex = $client->modeParam('favorite'); + my $hotKey = $client->modeParam('hotkey'); if (!defined $favIndex) { - $favIndex = $favorites->add(track($client), $track->title || $track->url); + ($favIndex, $hotKey) = $favorites->add(track($client), $track->title || $track->url, undef, undef, 'hotkey'); $client->showBriefly( { 'line' => [ $client->string('FAVORITES_ADDING'), $track->title || $track->url ] }); $client->modeParam('favorite', $favIndex); + $client->modeParam('hotkey', $hotKey); } else { @@ -527,6 +533,7 @@ Slim::Buttons::Common::pushModeLeft( $client, 'favorites.delete', { title => $track->title || $track->url, index => $favIndex, + hotkey=> $hotKey, depth => 2, } ); @@ -555,16 +562,11 @@ # special case favorites line, which must be determined dynamically if ($line2 eq 'FAVORITE') { my $favIndex = $client->modeParam('favorite'); + my $hotKey = $client->modeParam('hotkey'); if (!defined $favIndex) { $line2 = $client->string('FAVORITES_RIGHT_TO_ADD'); } else { - if ($favIndex =~ /^\d+$/) { - # existing favorite at top level - display favorite number starting at 1 (favs are zero based) - $line2 = $client->string('FAVORITES_FAVORITE') . ' ' . ($favIndex + 1); - } else { - # existing favorite not at top level - don't display number - $line2 = $client->string('FAVORITES_FAVORITE'); - } + $line2 = $client->string('FAVORITES_FAVORITE') . (defined $hotKey ? ' ' . $hotKey : ''); } } Index: Slim/Buttons/Common.pm =================================================================== --- Slim/Buttons/Common.pm (revision 17688) +++ Slim/Buttons/Common.pm (working copy) @@ -820,7 +820,7 @@ } if ($url && $title) { - Slim::Utils::Favorites->new($client)->add($url, $title, $type || 'audio', $parser); + my (undef, $hotkey) = Slim::Utils::Favorites->new($client)->add($url, $title, $type || 'audio', $parser, 'hotkey'); $client->showBriefly( { 'line' => [ $client->string('FAVORITES_ADDING'), $title ] } ); Index: Slim/Buttons/RemoteTrackInfo.pm =================================================================== --- Slim/Buttons/RemoteTrackInfo.pm (revision 17688) +++ Slim/Buttons/RemoteTrackInfo.pm (working copy) @@ -62,7 +62,7 @@ # # Only allow adding to favorites if the URL is something we can play. - my $favIndex; + my ($favIndex, $favHotkey); if ( $url && Slim::Utils::Favorites->enabled ) { @@ -72,14 +72,9 @@ my $client = shift; my $index = $client->modeParam('favorite'); + my $hotkey= $client->modeParam('hotkey'); if (defined $index) { - if ($index =~ /^\d+$/) { - # existing favorite at top level - display favorite number starting at 1 (favs are zero based) - return "{FAVORITES_FAVORITE}" . ' ' . ($index + 1); - } else { - # existing favorite not at top level - don't display number - return "{FAVORITES_FAVORITE}"; - } + return "{FAVORITES_FAVORITE} " . (defined $hotkey ? $hotkey : ''); } else { return "{FAVORITES_RIGHT_TO_ADD}"; } @@ -89,6 +84,7 @@ my $client = shift; my $favorites = Slim::Utils::Favorites->new($client) || return; my $index = $client->modeParam('favorite'); + my $hotkey= $client->modeParam('hotkey'); if (defined $index) { @@ -96,12 +92,14 @@ Slim::Buttons::Common::pushModeLeft( $client, 'favorites.delete', { title => $title, index => $index, - depth => 3, + hotkey=> $hotkey, + depth => 2, } ); } else { - $index = $favorites->add($url, $title); + ($index, $hotkey) = $favorites->add($url, $title, undef, undef, 'hotkey'); $client->modeParam('favorite', $index); + $client->modeParam('hotkey', $hotkey); $client->showBriefly( { 'line' => [ $client->string('FAVORITES_ADDING'), $client->modeParam('title') ] }); @@ -110,7 +108,7 @@ overlayRef => [ undef, $client->symbols('rightarrow') ], }; - $favIndex = Slim::Utils::Favorites->new($client)->findUrl($url); + ($favIndex, $favHotkey) = Slim::Utils::Favorites->new($client)->findUrl($url); } # now use another mode for the heavy lifting @@ -120,6 +118,7 @@ 'url' => $url, 'title' => $title, 'favorite' => $favIndex, + 'hotkey' => $favHotkey, # play music when play is pressed 'onPlay' => sub {