speed up browsing media library
the way media library was searching for albums was wrong and by the way totally inefficient.
This commit is contained in:
@@ -73,8 +73,6 @@
|
||||
#
|
||||
#song_library_format = "{%n - }{%t}|{%f}"
|
||||
#
|
||||
#media_library_album_format = "{(%y) }%b"
|
||||
#
|
||||
#tag_editor_album_format = "{(%y) }%b"
|
||||
#
|
||||
#browser_playlist_prefix = "$2playlist$9 "
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
#include "charset.h"
|
||||
#include "display.h"
|
||||
@@ -151,52 +150,46 @@ void MediaLibrary::Update()
|
||||
{
|
||||
Albums->Reset();
|
||||
TagList list;
|
||||
std::map<std::string, SearchConstraints, CaseInsensitiveSorting> maplist;
|
||||
locale_to_utf(Artists->Current());
|
||||
if (Config.media_lib_primary_tag == MPD_TAG_ITEM_ARTIST)
|
||||
Mpd->GetAlbums(Artists->Current(), list);
|
||||
else
|
||||
{
|
||||
Mpd->StartSearch(1);
|
||||
Mpd->AddSearch(Config.media_lib_primary_tag, Artists->Current());
|
||||
Mpd->StartFieldSearch(MPD_TAG_ITEM_ALBUM);
|
||||
Mpd->AddSearch(Config.media_lib_primary_tag, Artists->Current());
|
||||
Mpd->CommitSearch(list);
|
||||
}
|
||||
|
||||
// <mpd-0.14 doesn't support searching for empty tag
|
||||
if (Mpd->Version() > 13)
|
||||
{
|
||||
SongList noalbum_list;
|
||||
Mpd->StartSearch(1);
|
||||
TagList noalbum_list;
|
||||
Mpd->StartFieldSearch(MPD_TAG_ITEM_FILENAME);
|
||||
Mpd->AddSearch(Config.media_lib_primary_tag, Artists->Current());
|
||||
Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, "");
|
||||
Mpd->CommitSearch(noalbum_list);
|
||||
if (!noalbum_list.empty())
|
||||
Albums->AddOption(std::make_pair("<no album>", SearchConstraints("", "")));
|
||||
FreeSongList(noalbum_list);
|
||||
}
|
||||
|
||||
for (TagList::iterator it = list.begin(); it != list.end(); it++)
|
||||
{
|
||||
if (it->empty())
|
||||
continue;
|
||||
SongList l;
|
||||
Mpd->StartSearch(1);
|
||||
TagList l;
|
||||
Mpd->StartFieldSearch(MPD_TAG_ITEM_DATE);
|
||||
Mpd->AddSearch(Config.media_lib_primary_tag, Artists->Current());
|
||||
Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, *it);
|
||||
Mpd->CommitSearch(l);
|
||||
sort(l.begin(), l.end(), SortSongsByYear);
|
||||
for (SongList::const_iterator j = l.begin(); j != l.end(); j++)
|
||||
utf_to_locale(*it);
|
||||
if (l.empty())
|
||||
{
|
||||
utf_to_locale(*it);
|
||||
(*j)->Localize();
|
||||
maplist[(*j)->toString(Config.media_lib_album_format)] = SearchConstraints(*it, (*j)->GetYear());
|
||||
Albums->AddOption(std::make_pair(*it, SearchConstraints(*it, "")));
|
||||
continue;
|
||||
}
|
||||
FreeSongList(l);
|
||||
for (TagList::const_iterator j = l.begin(); j != l.end(); j++)
|
||||
Albums->AddOption(std::make_pair("(" + *j + ") " + *it, SearchConstraints(*it, *j)));
|
||||
}
|
||||
utf_to_locale(Artists->Current());
|
||||
for (std::map<std::string, SearchConstraints>::const_iterator it = maplist.begin(); it != maplist.end(); it++)
|
||||
Albums->AddOption(make_pair(it->first, it->second));
|
||||
Albums->Sort<CaseInsensitiveSorting>((*Albums)[0].first == "<no album>");
|
||||
Albums->Window::Clear();
|
||||
Albums->Refresh();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ class MediaLibrary : public Screen<Window>
|
||||
{
|
||||
struct SearchConstraints
|
||||
{
|
||||
SearchConstraints() { }
|
||||
SearchConstraints(const std::string &album, const std::string &year) : Album(album), Year(year) { }
|
||||
|
||||
std::string Album;
|
||||
|
||||
31
src/menu.h
31
src/menu.h
@@ -76,6 +76,11 @@ namespace NCurses
|
||||
bool isStatic;
|
||||
};
|
||||
|
||||
template <class ComparisonClass> static bool InternalSorting(Option *a, Option *b)
|
||||
{
|
||||
return ComparisonClass()(a->Item, b->Item);
|
||||
}
|
||||
|
||||
typedef typename std::vector<Option *>::iterator option_iterator;
|
||||
typedef typename std::vector<Option *>::const_iterator option_const_iterator;
|
||||
|
||||
@@ -128,6 +133,14 @@ namespace NCurses
|
||||
virtual void Reset();
|
||||
virtual void Clear(bool clrscr = 1);
|
||||
|
||||
template <class Compare> void Sort(size_t beginning = 0)
|
||||
{
|
||||
if (itsOptions.empty())
|
||||
return;
|
||||
sort(itsOptions.begin()+beginning, itsOptions.end(), InternalSorting<Compare>);
|
||||
ClearFiltered();
|
||||
}
|
||||
|
||||
void SetSelectPrefix(Buffer *b) { itsSelectedPrefix = b; }
|
||||
void SetSelectSuffix(Buffer *b) { itsSelectedSuffix = b; }
|
||||
|
||||
@@ -149,6 +162,8 @@ namespace NCurses
|
||||
virtual Menu<T> *EmptyClone() const;
|
||||
|
||||
protected:
|
||||
void ClearFiltered();
|
||||
|
||||
ItemDisplayer itsItemDisplayer;
|
||||
void *itsItemDisplayerUserdata;
|
||||
GetStringFunction itsGetStringFunction;
|
||||
@@ -462,14 +477,20 @@ template <class T> void NCurses::Menu<T>::Reset()
|
||||
itsBeginning = 0;
|
||||
}
|
||||
|
||||
template <class T> void NCurses::Menu<T>::ClearFiltered()
|
||||
{
|
||||
itsFilteredOptions.clear();
|
||||
itsFilteredRealPositions.clear();
|
||||
itsFilter.clear();
|
||||
itsOptionsPtr = &itsOptions;
|
||||
}
|
||||
|
||||
template <class T> void NCurses::Menu<T>::Clear(bool clrscr)
|
||||
{
|
||||
for (option_iterator it = itsOptions.begin(); it != itsOptions.end(); it++)
|
||||
delete *it;
|
||||
itsOptions.clear();
|
||||
itsFilteredOptions.clear();
|
||||
itsFilteredRealPositions.clear();
|
||||
itsFilter.clear();
|
||||
ClearFiltered();
|
||||
itsOptionsPtr = &itsOptions;
|
||||
if (clrscr)
|
||||
Window::Clear();
|
||||
@@ -557,12 +578,10 @@ template <class T> void NCurses::Menu<T>::ApplyFilter(const std::string &filter,
|
||||
{
|
||||
if (filter == itsFilter)
|
||||
return;
|
||||
ClearFiltered();
|
||||
itsFilter = filter;
|
||||
if (!case_sensitive)
|
||||
ToLower(itsFilter);
|
||||
itsFilteredRealPositions.clear();
|
||||
itsFilteredOptions.clear();
|
||||
itsOptionsPtr = &itsOptions;
|
||||
if (itsFilter.empty())
|
||||
return;
|
||||
for (size_t i = 0; i < beginning; i++)
|
||||
|
||||
@@ -689,29 +689,15 @@ void Connection::GetList(TagList &v, mpd_TagItems type) const
|
||||
char *item;
|
||||
while ((item = mpd_getNextTag(itsConnection, type)) != NULL)
|
||||
{
|
||||
v.push_back(item);
|
||||
if (item[0] != 0) // do not push empty item
|
||||
v.push_back(item);
|
||||
delete [] item;
|
||||
}
|
||||
mpd_finishCommand(itsConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::GetArtists(TagList &v) const
|
||||
{
|
||||
if (isConnected)
|
||||
{
|
||||
mpd_sendListCommand(itsConnection, MPD_TABLE_ARTIST, NULL);
|
||||
char *item;
|
||||
while ((item = mpd_getNextArtist(itsConnection)) != NULL)
|
||||
{
|
||||
v.push_back(item);
|
||||
delete [] item;
|
||||
}
|
||||
mpd_finishCommand(itsConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::GetAlbums(string artist, TagList &v) const
|
||||
void Connection::GetAlbums(const string &artist, TagList &v) const
|
||||
{
|
||||
if (isConnected)
|
||||
{
|
||||
@@ -719,7 +705,8 @@ void Connection::GetAlbums(string artist, TagList &v) const
|
||||
char *item;
|
||||
while ((item = mpd_getNextAlbum(itsConnection)) != NULL)
|
||||
{
|
||||
v.push_back(item);
|
||||
if (item[0] != 0) // do not push empty item
|
||||
v.push_back(item);
|
||||
delete [] item;
|
||||
}
|
||||
mpd_finishCommand(itsConnection);
|
||||
@@ -775,9 +762,8 @@ void Connection::CommitSearch(TagList &v) const
|
||||
char *tag = NULL;
|
||||
while ((tag = mpd_getNextTag(itsConnection, itsSearchedField)) != NULL)
|
||||
{
|
||||
string s_tag = tag;
|
||||
if (v.empty() || v.back() != s_tag)
|
||||
v.push_back(s_tag);
|
||||
if (tag[0] != 0) // do not push empty item
|
||||
v.push_back(tag);
|
||||
delete [] tag;
|
||||
}
|
||||
mpd_finishCommand(itsConnection);
|
||||
|
||||
@@ -180,8 +180,7 @@ namespace MPD
|
||||
|
||||
void GetPlaylists(TagList &) const;
|
||||
void GetList(TagList &, mpd_TagItems) const;
|
||||
void GetArtists(TagList &) const;
|
||||
void GetAlbums(std::string, TagList &) const;
|
||||
void GetAlbums(const std::string &, TagList &) const;
|
||||
void GetDirectory(const std::string &, ItemList &) const;
|
||||
void GetDirectoryRecursive(const std::string &, SongList &) const;
|
||||
void GetSongs(const std::string &, SongList &) const;
|
||||
|
||||
@@ -224,7 +224,6 @@ void DefaultConfiguration(ncmpcpp_config &conf)
|
||||
conf.song_status_format = "{(%l) }{%a - }{%t}|{%f}";
|
||||
conf.song_window_title_format = "{%a - }{%t}|{%f}";
|
||||
conf.song_library_format = "{%n - }{%t}|{%f}";
|
||||
conf.media_lib_album_format = "{(%y) }%b";
|
||||
conf.tag_editor_album_format = "{(%y) }%b";
|
||||
conf.browser_playlist_prefix << clRed << "(playlist)" << clEnd << ' ';
|
||||
conf.pattern = "%n - %t";
|
||||
@@ -506,11 +505,6 @@ void ReadConfiguration(ncmpcpp_config &conf)
|
||||
if (!v.empty())
|
||||
conf.song_library_format = v;
|
||||
}
|
||||
else if (cl.find("media_library_album_format") != string::npos)
|
||||
{
|
||||
if (!v.empty())
|
||||
conf.media_lib_album_format = v;
|
||||
}
|
||||
else if (cl.find("tag_editor_album_format") != string::npos)
|
||||
{
|
||||
if (!v.empty())
|
||||
|
||||
@@ -108,7 +108,6 @@ struct ncmpcpp_config
|
||||
std::string song_status_format;
|
||||
std::string song_window_title_format;
|
||||
std::string song_library_format;
|
||||
std::string media_lib_album_format;
|
||||
std::string tag_editor_album_format;
|
||||
std::string external_editor;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user