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