void MediaLibrary::LocateSong(const MPD::Song &s) { std::string primary_tag = s.get(Config.media_lib_primary_tag); if (primary_tag.empty()) { std::string item_type = boost::locale::to_lower( tagTypeToString(Config.media_lib_primary_tag)); Statusbar::printf("Can't use this function because the song has no %s tag", item_type); return; } if (!s.isFromDatabase()) { Statusbar::print("Song is not from the database"); return; } if (myScreen != this) switchTo(); Statusbar::put() << "Jumping to song..."; Global::wFooter->refresh(); if (!hasTwoColumns) { if (Tags.empty()) update(); if (!MoveToTag(Tags, primary_tag)) { // The tag could not be found. Since this was called from an existing // song, the tag should exist in the library, but it was not listed by // list/listallinfo. This is the case with some players where it is not // possible to list all of the library, e.g. mopidy with mopidy-spotify. // To workaround this we simply insert the missing tag. Tags.addItem(PrimaryTag(primary_tag, s.getMTime())); std::sort(Tags.beginV(), Tags.endV(), SortPrimaryTags()); Tags.refresh(); MoveToTag(Tags, primary_tag); } Albums.clear(); } if (Albums.empty()) update(); // When you locate a song in the media library, if no albums or no songs // are found, set the active column to the previous one (tags if no albums, // and albums if no songs). This makes sure that the active column is not // empty, which may make it impossible to move out of. // // The problem was if you highlight some song in the rightmost column in // the media browser and then go to some other window and select locate // song. If the tag or album it looked up in the media library was // empty, the selection would stay in the songs column while it was empty. // This made the selection impossible to change. // // This only is a problem if a song has some tag or album for which the // find command doesn't return any results. This should never really happen // unless there is some inconsistency in the player. However, it may // happen, so we need to handle it. // // Note: We don't want to return when no albums are found in two column // mode. In this case, we try to insert the album, as we do with tags when // they are not found. if (hasTwoColumns || !Albums.empty()) { if (!MoveToAlbum(Albums, primary_tag, s)) { // The album could not be found, insert it if in two column mode. // See comment about tags not found above. This is the equivalent // for two column mode. Albums.addItem(AlbumEntry( Album(primary_tag, s.getAlbum(), s.getDate(), s.getMTime()) )); std::sort(Albums.beginV(), Albums.endV(), SortAlbumEntries()); Albums.refresh(); MoveToAlbum(Albums, primary_tag, s); } Songs.clear(); update(); if (!Songs.empty()) { if (s != Songs.current()->value()) { auto begin = Songs.beginV(), end = Songs.endV(); auto it = std::find(begin, end, s); if (it != end) Songs.highlight(it-begin); } nextColumn(); nextColumn(); } else // invalid album was added, clear the list Albums.clear(); } else // invalid tag was added, clear the list Tags.clear(); refresh(); }
void MediaLibrary::LocateSong(const MPD::Song &s) { std::string primary_tag = s.get(Config.media_lib_primary_tag); if (primary_tag.empty()) { std::string item_type = boost::locale::to_lower( tagTypeToString(Config.media_lib_primary_tag)); Statusbar::msg("Can't use this function because the song has no %s tag set", item_type.c_str()); return; } if (myScreen != this) switchTo(); Statusbar::put() << "Jumping to song..."; Global::wFooter->refresh(); if (!hasTwoColumns) { Tags.showAll(); if (Tags.empty()) update(); if (primary_tag != Tags.current().value().tag()) { for (size_t i = 0; i < Tags.size(); ++i) { if (primary_tag == Tags[i].value().tag()) { Tags.highlight(i); Albums.clear(); Songs.clear(); break; } } } } Albums.showAll(); if (Albums.empty()) update(); std::string album = s.getAlbum(); std::string date = s.getDate(); if ((hasTwoColumns && Albums.current().value().entry().tag() != primary_tag) || album != Albums.current().value().entry().album() || date != Albums.current().value().entry().date()) { for (size_t i = 0; i < Albums.size(); ++i) { if ((!hasTwoColumns || Albums[i].value().entry().tag() == primary_tag) && album == Albums[i].value().entry().album() && date == Albums[i].value().entry().date()) { Albums.highlight(i); Songs.clear(); break; } } } Songs.showAll(); if (Songs.empty()) update(); if (s.getHash() != Songs.current().value().getHash()) { for (size_t i = 0; i < Songs.size(); ++i) { if (s.getHash() == Songs[i].value().getHash()) { Songs.highlight(i); break; } } } Tags.setHighlightColor(Config.main_highlight_color); Albums.setHighlightColor(Config.main_highlight_color); Songs.setHighlightColor(Config.active_column_color); w = &Songs; refresh(); }