playlist: rewrite sorting so it's much less cryptic

This commit is contained in:
Andrzej Rybczak
2012-08-14 23:55:01 +02:00
parent b7999b499f
commit e729ab0a38
4 changed files with 35 additions and 36 deletions

View File

@@ -916,7 +916,6 @@ bool MPD::Connection::AddRandomTag(mpd_tag_type tag, size_t number)
} }
else else
{ {
srand(time(0));
std::random_shuffle(tags.begin(), tags.end()); std::random_shuffle(tags.begin(), tags.end());
TagList::const_iterator it = tags.begin()+rand()%(tags.size()-number); TagList::const_iterator it = tags.begin()+rand()%(tags.size()-number);
for (size_t i = 0; i < number && it != tags.end(); ++i) for (size_t i = 0; i < number && it != tags.end(); ++i)

View File

@@ -94,6 +94,7 @@ namespace
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
srand(time(0));
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
Config.CheckForCommandLineConfigFilePath(argv, argc); Config.CheckForCommandLineConfigFilePath(argv, argc);

View File

@@ -182,39 +182,14 @@ void Playlist::EnterPressed()
return; return;
} }
ShowMessage("Sorting playlist..."); MPD::SongList playlist;
MPD::SongList playlist, cmp;
playlist.reserve(end-beginning); playlist.reserve(end-beginning);
for (size_t i = beginning; i < end; ++i) for (size_t i = beginning; i < end; ++i)
{
(*Items)[i].SetPosition(i);
playlist.push_back(&(*Items)[i]); playlist.push_back(&(*Items)[i]);
}
cmp = playlist;
sort(playlist.begin(), playlist.end(), Playlist::Sorting);
if (playlist == cmp)
{
ShowMessage("Playlist is already sorted");
return;
}
ShowMessage("Sorting...");
Mpd.StartCommandsList(); Mpd.StartCommandsList();
do QuickSort(playlist.begin(), playlist.end(), playlist.begin());
{
for (size_t i = 0, j = beginning; i < playlist.size(); ++i, ++j)
{
if (playlist[i]->GetPosition() > j)
{
Mpd.Swap(playlist[i]->GetPosition(), j);
std::swap(cmp[playlist[i]->GetPosition()-beginning], cmp[i]);
Items->Swap(playlist[i]->GetPosition(), j);
}
cmp[i]->SetPosition(j);
}
}
while (playlist != cmp);
if (Mpd.CommitCommandsList()) if (Mpd.CommitCommandsList())
ShowMessage("Playlist sorted"); ShowMessage("Playlist sorted");
w = Items; w = Items;
@@ -445,13 +420,23 @@ void Playlist::EnableHighlighting()
UpdateTimer(); UpdateTimer();
} }
bool Playlist::Sorting(MPD::Song *a, MPD::Song *b) void Playlist::QuickSort(MPD::SongList::iterator first, MPD::SongList::iterator last, MPD::SongList::iterator begin)
{ {
CaseInsensitiveStringComparison cmp; if (last-first > 1)
for (size_t i = 0; i < SortOptions; ++i) {
if (int ret = cmp(a->GetTags((*SortDialog)[i].second), b->GetTags((*SortDialog)[i].second))) MPD::SongList::iterator pivot = first+rand()%(last-first);
return ret < 0; IterSwap(pivot, last-1, begin);
return a->GetPosition() < b->GetPosition(); pivot = last-1;
MPD::SongList::iterator tmp = first;
for (MPD::SongList::iterator i = first; i != pivot; ++i)
if (SongComp(*i, *pivot))
IterSwap(i, tmp++, begin);
IterSwap(tmp, pivot, begin);
QuickSort(first, tmp, begin);
QuickSort(tmp+1, last, begin);
}
} }
std::string Playlist::TotalLength() std::string Playlist::TotalLength()

View File

@@ -105,7 +105,21 @@ class Playlist : public Screen<Window>
time_t itsTimer; time_t itsTimer;
static bool Sorting(MPD::Song *a, MPD::Song *b); // stuff for sorting playlist
static void QuickSort(MPD::SongList::iterator first, MPD::SongList::iterator last, MPD::SongList::iterator begin);
inline static void IterSwap(MPD::SongList::iterator a, MPD::SongList::iterator b, MPD::SongList::iterator begin)
{
iter_swap(a, b);
Mpd.Swap(a-begin, b-begin);
}
inline static bool SongComp(MPD::Song *a, MPD::Song *b)
{
CaseInsensitiveStringComparison cmp;
for (size_t i = 0; i < SortOptions; ++i)
if (int ret = cmp(a->GetTags((*SortDialog)[i].second), b->GetTags((*SortDialog)[i].second)))
return ret < 0;
return a->GetPosition() < b->GetPosition();
}
static Menu< std::pair<std::string, MPD::Song::GetFunction> > *SortDialog; static Menu< std::pair<std::string, MPD::Song::GetFunction> > *SortDialog;
static const size_t SortOptions; static const size_t SortOptions;