You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.7 KiB
111 lines
3.7 KiB
/*************************************************************************** |
|
* Copyright (C) 2008-2016 by Andrzej Rybczak * |
|
* electricityispower@gmail.com * |
|
* * |
|
* This program is free software; you can redistribute it and/or modify * |
|
* it under the terms of the GNU General Public License as published by * |
|
* the Free Software Foundation; either version 2 of the License, or * |
|
* (at your option) any later version. * |
|
* * |
|
* This program is distributed in the hope that it will be useful, * |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of * |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
|
* GNU General Public License for more details. * |
|
* * |
|
* You should have received a copy of the GNU General Public License * |
|
* along with this program; if not, write to the * |
|
* Free Software Foundation, Inc., * |
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * |
|
***************************************************************************/ |
|
|
|
#include <locale> |
|
#include "comparators.h" |
|
#include "format_impl.h" |
|
#include "utility/string.h" |
|
|
|
namespace { |
|
|
|
bool hasTheWord(const std::string &s) |
|
{ |
|
return s.length() >= 4 |
|
&& (s[0] == 't' || s[0] == 'T') |
|
&& (s[1] == 'h' || s[1] == 'H') |
|
&& (s[2] == 'e' || s[2] == 'E') |
|
&& (s[3] == ' '); |
|
} |
|
|
|
} |
|
|
|
int LocaleStringComparison::compare(const char *a, size_t a_len, const char *b, size_t b_len) const |
|
{ |
|
size_t ac_off = 0, bc_off = 0; |
|
if (m_ignore_the) |
|
{ |
|
if (hasTheWord(a)) |
|
ac_off += 4; |
|
if (hasTheWord(b)) |
|
bc_off += 4; |
|
} |
|
return std::use_facet<std::collate<char>>(m_locale).compare( |
|
a+ac_off, a+a_len, b+bc_off, b+b_len |
|
); |
|
} |
|
|
|
bool LocaleBasedItemSorting::operator()(const MPD::Item &a, const MPD::Item &b) const |
|
{ |
|
bool result = false; |
|
if (a.type() == b.type()) |
|
{ |
|
switch (m_sort_mode) |
|
{ |
|
case SortMode::Name: |
|
switch (a.type()) |
|
{ |
|
case MPD::Item::Type::Directory: |
|
result = m_cmp(a.directory().path(), b.directory().path()); |
|
break; |
|
case MPD::Item::Type::Playlist: |
|
result = m_cmp(a.playlist().path(), b.playlist().path()); |
|
break; |
|
case MPD::Item::Type::Song: |
|
result = m_cmp(a.song(), b.song()); |
|
break; |
|
} |
|
break; |
|
case SortMode::CustomFormat: |
|
switch (a.type()) |
|
{ |
|
case MPD::Item::Type::Directory: |
|
result = m_cmp(a.directory().path(), b.directory().path()); |
|
break; |
|
case MPD::Item::Type::Playlist: |
|
result = m_cmp(a.playlist().path(), b.playlist().path()); |
|
break; |
|
case MPD::Item::Type::Song: |
|
result = m_cmp(Format::stringify<char>(Config.browser_sort_format, &a.song()), |
|
Format::stringify<char>(Config.browser_sort_format, &b.song())); |
|
break; |
|
} |
|
break; |
|
case SortMode::ModificationTime: |
|
switch (a.type()) |
|
{ |
|
case MPD::Item::Type::Directory: |
|
result = a.directory().lastModified() > b.directory().lastModified(); |
|
break; |
|
case MPD::Item::Type::Playlist: |
|
result = a.playlist().lastModified() > b.playlist().lastModified(); |
|
break; |
|
case MPD::Item::Type::Song: |
|
result = a.song().getMTime() > b.song().getMTime(); |
|
break; |
|
} |
|
break; |
|
case SortMode::NoOp: |
|
throw std::logic_error("can't sort with NoOp sorting mode"); |
|
} |
|
} |
|
else |
|
result = a.type() < b.type(); |
|
return result; |
|
}
|
|
|