initial restoration of support for encodings different than utf-8
This commit is contained in:
@@ -18,12 +18,32 @@
|
|||||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <boost/locale/encoding.hpp>
|
#include <boost/locale.hpp>
|
||||||
#include "charset.h"
|
#include "charset.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
namespace Charset {//
|
namespace Charset {//
|
||||||
|
|
||||||
|
std::locale internalLocale()
|
||||||
|
{
|
||||||
|
boost::locale::generator gen;
|
||||||
|
std::locale loc = gen("");
|
||||||
|
bool is_utf = std::use_facet<boost::locale::info>(loc).utf8();
|
||||||
|
std::string name = std::use_facet<boost::locale::info>(loc).name();
|
||||||
|
if (!is_utf && name != "C" && name != "POSIX")
|
||||||
|
{
|
||||||
|
// if current locale does not use unicode, use variant of this
|
||||||
|
// locale with utf8 as ncmpcpp uses utf8 internally and we need
|
||||||
|
// current locale for sorting, case conversions etc.
|
||||||
|
std::string new_name = std::use_facet<boost::locale::info>(loc).language()
|
||||||
|
+ "_"
|
||||||
|
+ std::use_facet<boost::locale::info>(loc).country()
|
||||||
|
+ ".UTF-8";
|
||||||
|
loc = gen(new_name);
|
||||||
|
}
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
std::string toUtf8From(std::string s, const char *charset)
|
std::string toUtf8From(std::string s, const char *charset)
|
||||||
{
|
{
|
||||||
return boost::locale::conv::to_utf<char>(s, charset);
|
return boost::locale::conv::to_utf<char>(s, charset);
|
||||||
@@ -37,15 +57,15 @@ std::string fromUtf8To(std::string s, const char *charset)
|
|||||||
std::string utf8ToLocale(std::string s)
|
std::string utf8ToLocale(std::string s)
|
||||||
{
|
{
|
||||||
return Config.system_encoding.empty()
|
return Config.system_encoding.empty()
|
||||||
? s
|
? s
|
||||||
: boost::locale::conv::from_utf<char>(s, Config.system_encoding);
|
: boost::locale::conv::from_utf<char>(s, Config.system_encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string localeToUtf8(std::string s)
|
std::string localeToUtf8(std::string s)
|
||||||
{
|
{
|
||||||
return Config.system_encoding.empty()
|
return Config.system_encoding.empty()
|
||||||
? s
|
? s
|
||||||
: boost::locale::conv::to_utf<char>(s, Config.system_encoding);
|
: boost::locale::conv::to_utf<char>(s, Config.system_encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,13 @@
|
|||||||
#ifndef NCMPCPP_CHARSET_H
|
#ifndef NCMPCPP_CHARSET_H
|
||||||
#define NCMPCPP_CHARSET_H
|
#define NCMPCPP_CHARSET_H
|
||||||
|
|
||||||
|
#include <locale>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Charset {//
|
namespace Charset {//
|
||||||
|
|
||||||
|
std::locale internalLocale();
|
||||||
|
|
||||||
std::string toUtf8From(std::string s, const char *charset);
|
std::string toUtf8From(std::string s, const char *charset);
|
||||||
std::string fromUtf8To(std::string s, const char *charset);
|
std::string fromUtf8To(std::string s, const char *charset);
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include "browser.h"
|
#include "browser.h"
|
||||||
|
#include "charset.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "song_info.h"
|
#include "song_info.h"
|
||||||
@@ -108,7 +109,7 @@ void showSongs(NC::Menu<T> &menu, const MPD::Song &s, const ProxySongList &pl, c
|
|||||||
setProperties(menu, s, pl, separate_albums, is_now_playing, is_selected, discard_colors);
|
setProperties(menu, s, pl, separate_albums, is_now_playing, is_selected, discard_colors);
|
||||||
|
|
||||||
size_t y = menu.getY();
|
size_t y = menu.getY();
|
||||||
std::string line = s.toString(format, Config.tags_separator, "$");
|
std::string line = Charset::utf8ToLocale(s.toString(format, Config.tags_separator, "$"));
|
||||||
for (auto it = line.begin(); it != line.end(); ++it)
|
for (auto it = line.begin(); it != line.end(); ++it)
|
||||||
{
|
{
|
||||||
if (*it == '$')
|
if (*it == '$')
|
||||||
@@ -222,7 +223,8 @@ void showSongsInColumns(NC::Menu<T> &menu, const MPD::Song &s, const ProxySongLi
|
|||||||
for (size_t i = 0; i < it->type.length(); ++i)
|
for (size_t i = 0; i < it->type.length(); ++i)
|
||||||
{
|
{
|
||||||
MPD::Song::GetFunction get = charToGetFunction(it->type[i]);
|
MPD::Song::GetFunction get = charToGetFunction(it->type[i]);
|
||||||
tag = ToWString(get ? s.getTags(get, Config.tags_separator) : "");
|
assert(get);
|
||||||
|
tag = ToWString(Charset::utf8ToLocale(s.getTags(get, Config.tags_separator)));
|
||||||
if (!tag.empty())
|
if (!tag.empty())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -326,11 +328,11 @@ std::string Display::Columns(size_t list_width)
|
|||||||
if (it->right_alignment)
|
if (it->right_alignment)
|
||||||
{
|
{
|
||||||
result += std::string(x_off, KEY_SPACE);
|
result += std::string(x_off, KEY_SPACE);
|
||||||
result += ToString(name);
|
result += Charset::utf8ToLocale(ToString(name));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result += ToString(name);
|
result += Charset::utf8ToLocale(ToString(name));
|
||||||
result += std::string(x_off, KEY_SPACE);
|
result += std::string(x_off, KEY_SPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,30 +366,29 @@ void Display::Tags(NC::Menu<MPD::MutableSong> &menu)
|
|||||||
size_t i = myTagEditor->TagTypes->choice();
|
size_t i = myTagEditor->TagTypes->choice();
|
||||||
if (i < 11)
|
if (i < 11)
|
||||||
{
|
{
|
||||||
ShowTag(menu, s.getTags(SongInfo::Tags[i].Get, Config.tags_separator));
|
ShowTag(menu, Charset::utf8ToLocale(s.getTags(SongInfo::Tags[i].Get, Config.tags_separator)));
|
||||||
}
|
}
|
||||||
else if (i == 12)
|
else if (i == 12)
|
||||||
{
|
{
|
||||||
if (s.getNewURI().empty())
|
if (s.getNewURI().empty())
|
||||||
menu << s.getName();
|
menu << Charset::utf8ToLocale(s.getName());
|
||||||
else
|
else
|
||||||
menu << s.getName() << Config.color2 << " -> " << NC::clEnd << s.getNewURI();
|
menu << Charset::utf8ToLocale(s.getName())
|
||||||
|
<< Config.color2 << " -> " << NC::clEnd
|
||||||
|
<< Charset::utf8ToLocale(s.getNewURI());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // HAVE_TAGLIB_H
|
#endif // HAVE_TAGLIB_H
|
||||||
|
|
||||||
void Display::Outputs(NC::Menu<MPD::Output> &menu)
|
|
||||||
{
|
|
||||||
menu << menu.drawn()->value().name();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Display::Items(NC::Menu<MPD::Item> &menu, const ProxySongList &pl)
|
void Display::Items(NC::Menu<MPD::Item> &menu, const ProxySongList &pl)
|
||||||
{
|
{
|
||||||
const MPD::Item &item = menu.drawn()->value();
|
const MPD::Item &item = menu.drawn()->value();
|
||||||
switch (item.type)
|
switch (item.type)
|
||||||
{
|
{
|
||||||
case MPD::itDirectory:
|
case MPD::itDirectory:
|
||||||
menu << "[" << getBasename(item.name) << "]";
|
menu << "["
|
||||||
|
<< Charset::utf8ToLocale(getBasename(item.name))
|
||||||
|
<< "]";
|
||||||
break;
|
break;
|
||||||
case MPD::itSong:
|
case MPD::itSong:
|
||||||
if (!Config.columns_in_browser)
|
if (!Config.columns_in_browser)
|
||||||
@@ -396,12 +397,13 @@ void Display::Items(NC::Menu<MPD::Item> &menu, const ProxySongList &pl)
|
|||||||
showSongsInColumns(menu, *item.song, pl);
|
showSongsInColumns(menu, *item.song, pl);
|
||||||
break;
|
break;
|
||||||
case MPD::itPlaylist:
|
case MPD::itPlaylist:
|
||||||
menu << Config.browser_playlist_prefix << getBasename(item.name);
|
menu << Config.browser_playlist_prefix
|
||||||
|
<< Charset::utf8ToLocale(getBasename(item.name));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::SearchEngine(NC::Menu<SEItem> &menu, const ProxySongList &pl)
|
void Display::SEItems(NC::Menu<SEItem> &menu, const ProxySongList &pl)
|
||||||
{
|
{
|
||||||
const SEItem &si = menu.drawn()->value();
|
const SEItem &si = menu.drawn()->value();
|
||||||
if (si.isSong())
|
if (si.isSong())
|
||||||
|
|||||||
@@ -30,21 +30,13 @@ namespace Display {//
|
|||||||
|
|
||||||
std::string Columns(size_t);
|
std::string Columns(size_t);
|
||||||
|
|
||||||
template <typename ItemT>
|
|
||||||
void Default(NC::Menu<ItemT> &menu) { menu << menu.drawn()->value(); }
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
void Pair(NC::Menu< std::pair<A, B> > &menu) { menu << menu.drawn()->value().first; }
|
|
||||||
|
|
||||||
void SongsInColumns(NC::Menu<MPD::Song> &menu, const ProxySongList &pl);
|
void SongsInColumns(NC::Menu<MPD::Song> &menu, const ProxySongList &pl);
|
||||||
|
|
||||||
void Songs(NC::Menu<MPD::Song> &menu, const ProxySongList &pl, const std::string &format);
|
void Songs(NC::Menu<MPD::Song> &menu, const ProxySongList &pl, const std::string &format);
|
||||||
|
|
||||||
void Tags(NC::Menu<MPD::MutableSong> &menu);
|
void Tags(NC::Menu<MPD::MutableSong> &menu);
|
||||||
|
|
||||||
void Outputs(NC::Menu<MPD::Output> &menu);
|
void SEItems(NC::Menu<SEItem> &menu, const ProxySongList &pl);
|
||||||
|
|
||||||
void SearchEngine(NC::Menu<SEItem> &menu, const ProxySongList &pl);
|
|
||||||
|
|
||||||
void Items(NC::Menu<MPD::Item> &menu, const ProxySongList &pl);
|
void Items(NC::Menu<MPD::Item> &menu, const ProxySongList &pl);
|
||||||
|
|
||||||
|
|||||||
@@ -473,7 +473,7 @@ template <typename T> void ShowTime(T &buf, size_t length, bool short_names)
|
|||||||
buf << length << cnv(short_names ? "s" : (length == 1 ? " second" : " seconds"));
|
buf << length << cnv(short_names ? "s" : (length == 1 ? " second" : " seconds"));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void ShowTag(T &buf, const std::string &tag)
|
template <typename BufferT> void ShowTag(BufferT &buf, const std::string &tag)
|
||||||
{
|
{
|
||||||
if (tag.empty())
|
if (tag.empty())
|
||||||
buf << Config.empty_tags_color << Config.empty_tag << NC::clEnd;
|
buf << Config.empty_tags_color << Config.empty_tag << NC::clEnd;
|
||||||
|
|||||||
@@ -64,9 +64,6 @@ bool TagEntryMatcher(const Regex &rx, const MediaLibrary::PrimaryTag &tagmtime);
|
|||||||
bool AlbumEntryMatcher(const Regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter);
|
bool AlbumEntryMatcher(const Regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter);
|
||||||
bool SongEntryMatcher(const Regex &rx, const MPD::Song &s);
|
bool SongEntryMatcher(const Regex &rx, const MPD::Song &s);
|
||||||
|
|
||||||
void DisplayAlbums(NC::Menu<AlbumEntry> &menu);
|
|
||||||
void DisplayPrimaryTags(NC::Menu<MediaLibrary::PrimaryTag> &menu);
|
|
||||||
|
|
||||||
struct SortSongs {
|
struct SortSongs {
|
||||||
static const std::array<MPD::Song::GetFunction, 3> GetFuns;
|
static const std::array<MPD::Song::GetFunction, 3> GetFuns;
|
||||||
|
|
||||||
@@ -156,7 +153,13 @@ MediaLibrary::MediaLibrary()
|
|||||||
Tags.centeredCursor(Config.centered_cursor);
|
Tags.centeredCursor(Config.centered_cursor);
|
||||||
Tags.setSelectedPrefix(Config.selected_item_prefix);
|
Tags.setSelectedPrefix(Config.selected_item_prefix);
|
||||||
Tags.setSelectedSuffix(Config.selected_item_suffix);
|
Tags.setSelectedSuffix(Config.selected_item_suffix);
|
||||||
Tags.setItemDisplayer(DisplayPrimaryTags);
|
Tags.setItemDisplayer([](NC::Menu<PrimaryTag> &menu) {
|
||||||
|
const std::string &tag = menu.drawn()->value().tag();
|
||||||
|
if (tag.empty())
|
||||||
|
menu << Config.empty_tag;
|
||||||
|
else
|
||||||
|
menu << Charset::utf8ToLocale(tag);
|
||||||
|
});
|
||||||
|
|
||||||
Albums = NC::Menu<AlbumEntry>(itsMiddleColStartX, MainStartY, itsMiddleColWidth, MainHeight, Config.titles_visibility ? "Albums" : "", Config.main_color, NC::brNone);
|
Albums = NC::Menu<AlbumEntry>(itsMiddleColStartX, MainStartY, itsMiddleColWidth, MainHeight, Config.titles_visibility ? "Albums" : "", Config.main_color, NC::brNone);
|
||||||
Albums.setHighlightColor(Config.main_highlight_color);
|
Albums.setHighlightColor(Config.main_highlight_color);
|
||||||
@@ -164,7 +167,9 @@ MediaLibrary::MediaLibrary()
|
|||||||
Albums.centeredCursor(Config.centered_cursor);
|
Albums.centeredCursor(Config.centered_cursor);
|
||||||
Albums.setSelectedPrefix(Config.selected_item_prefix);
|
Albums.setSelectedPrefix(Config.selected_item_prefix);
|
||||||
Albums.setSelectedSuffix(Config.selected_item_suffix);
|
Albums.setSelectedSuffix(Config.selected_item_suffix);
|
||||||
Albums.setItemDisplayer(DisplayAlbums);
|
Albums.setItemDisplayer([](NC::Menu<AlbumEntry> &menu) {
|
||||||
|
menu << Charset::utf8ToLocale(AlbumToString(menu.drawn()->value()));
|
||||||
|
});
|
||||||
|
|
||||||
Songs = NC::Menu<MPD::Song>(itsRightColStartX, MainStartY, itsRightColWidth, MainHeight, Config.titles_visibility ? "Songs" : "", Config.main_color, NC::brNone);
|
Songs = NC::Menu<MPD::Song>(itsRightColStartX, MainStartY, itsRightColWidth, MainHeight, Config.titles_visibility ? "Songs" : "", Config.main_color, NC::brNone);
|
||||||
Songs.setHighlightColor(Config.main_highlight_color);
|
Songs.setHighlightColor(Config.main_highlight_color);
|
||||||
@@ -1033,20 +1038,4 @@ bool SongEntryMatcher(const Regex &rx, const MPD::Song &s)
|
|||||||
return rx.match(SongToString(s));
|
return rx.match(SongToString(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
|
|
||||||
void DisplayAlbums(NC::Menu<AlbumEntry> &menu)
|
|
||||||
{
|
|
||||||
menu << AlbumToString(menu.drawn()->value());
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayPrimaryTags(NC::Menu<MediaLibrary::PrimaryTag> &menu)
|
|
||||||
{
|
|
||||||
const std::string &tag = menu.drawn()->value().tag();
|
|
||||||
if (tag.empty())
|
|
||||||
menu << Config.empty_tag;
|
|
||||||
else
|
|
||||||
menu << tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <boost/locale.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@@ -33,6 +34,7 @@
|
|||||||
#include "actions.h"
|
#include "actions.h"
|
||||||
#include "bindings.h"
|
#include "bindings.h"
|
||||||
#include "browser.h"
|
#include "browser.h"
|
||||||
|
#include "charset.h"
|
||||||
#include "cmdargs.h"
|
#include "cmdargs.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@@ -91,7 +93,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
std::srand(std::time(0));
|
std::srand(std::time(0));
|
||||||
std::setlocale(LC_ALL, "");
|
std::setlocale(LC_ALL, "");
|
||||||
std::locale::global(std::locale(""));
|
std::locale::global(Charset::internalLocale());
|
||||||
|
|
||||||
Config.CheckForCommandLineConfigFilePath(argv, argc);
|
Config.CheckForCommandLineConfigFilePath(argv, argc);
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#ifdef ENABLE_OUTPUTS
|
#ifdef ENABLE_OUTPUTS
|
||||||
|
|
||||||
|
#include "charset.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
@@ -42,7 +43,9 @@ Outputs::Outputs()
|
|||||||
w.cyclicScrolling(Config.use_cyclic_scrolling);
|
w.cyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
w.centeredCursor(Config.centered_cursor);
|
w.centeredCursor(Config.centered_cursor);
|
||||||
w.setHighlightColor(Config.main_highlight_color);
|
w.setHighlightColor(Config.main_highlight_color);
|
||||||
w.setItemDisplayer(Display::Outputs);
|
w.setItemDisplayer([](NC::Menu<MPD::Output> &menu) {
|
||||||
|
menu << Charset::utf8ToLocale(menu.drawn()->value().name());
|
||||||
|
});
|
||||||
FetchList();
|
FetchList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ PlaylistEditor::PlaylistEditor()
|
|||||||
Playlists.centeredCursor(Config.centered_cursor);
|
Playlists.centeredCursor(Config.centered_cursor);
|
||||||
Playlists.setSelectedPrefix(Config.selected_item_prefix);
|
Playlists.setSelectedPrefix(Config.selected_item_prefix);
|
||||||
Playlists.setSelectedSuffix(Config.selected_item_suffix);
|
Playlists.setSelectedSuffix(Config.selected_item_suffix);
|
||||||
Playlists.setItemDisplayer(Display::Default<std::string>);
|
Playlists.setItemDisplayer([](NC::Menu<std::string> &menu) {
|
||||||
|
menu << Charset::utf8ToLocale(menu.drawn()->value());
|
||||||
|
});
|
||||||
|
|
||||||
Content = NC::Menu<MPD::Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, Config.titles_visibility ? "Playlist content" : "", Config.main_color, NC::brNone);
|
Content = NC::Menu<MPD::Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, Config.titles_visibility ? "Playlist content" : "", Config.main_color, NC::brNone);
|
||||||
Content.setHighlightColor(Config.main_highlight_color);
|
Content.setHighlightColor(Config.main_highlight_color);
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ SearchEngine::SearchEngine()
|
|||||||
w.setHighlightColor(Config.main_highlight_color);
|
w.setHighlightColor(Config.main_highlight_color);
|
||||||
w.cyclicScrolling(Config.use_cyclic_scrolling);
|
w.cyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
w.centeredCursor(Config.centered_cursor);
|
w.centeredCursor(Config.centered_cursor);
|
||||||
w.setItemDisplayer(std::bind(Display::SearchEngine, _1, proxySongList()));
|
w.setItemDisplayer(std::bind(Display::SEItems, _1, proxySongList()));
|
||||||
w.setSelectedPrefix(Config.selected_item_prefix);
|
w.setSelectedPrefix(Config.selected_item_prefix);
|
||||||
w.setSelectedSuffix(Config.selected_item_suffix);
|
w.setSelectedSuffix(Config.selected_item_suffix);
|
||||||
SearchMode = &SearchModes[Config.search_engine_default_search_mode];
|
SearchMode = &SearchModes[Config.search_engine_default_search_mode];
|
||||||
|
|||||||
@@ -27,53 +27,7 @@
|
|||||||
#include "mpdpp.h"
|
#include "mpdpp.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
struct SEItem
|
struct SearchEngine: Screen<NC::Menu<struct SEItem>>, Filterable, HasSongs, Searchable, Tabbable
|
||||||
{
|
|
||||||
SEItem() : isThisSong(false), itsBuffer(0) { }
|
|
||||||
SEItem(NC::Buffer *buf) : isThisSong(false), itsBuffer(buf) { }
|
|
||||||
SEItem(const MPD::Song &s) : isThisSong(true), itsSong(s) { }
|
|
||||||
SEItem(const SEItem &ei) { *this = ei; }
|
|
||||||
~SEItem() {
|
|
||||||
if (!isThisSong)
|
|
||||||
delete itsBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
NC::Buffer &mkBuffer() {
|
|
||||||
assert(!isThisSong);
|
|
||||||
delete itsBuffer;
|
|
||||||
itsBuffer = new NC::Buffer();
|
|
||||||
return *itsBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSong() const { return isThisSong; }
|
|
||||||
|
|
||||||
NC::Buffer &buffer() { assert(!isThisSong && itsBuffer); return *itsBuffer; }
|
|
||||||
MPD::Song &song() { assert(isThisSong); return itsSong; }
|
|
||||||
|
|
||||||
const NC::Buffer &buffer() const { assert(!isThisSong && itsBuffer); return *itsBuffer; }
|
|
||||||
const MPD::Song &song() const { assert(isThisSong); return itsSong; }
|
|
||||||
|
|
||||||
SEItem &operator=(const SEItem &se) {
|
|
||||||
if (this == &se)
|
|
||||||
return *this;
|
|
||||||
isThisSong = se.isThisSong;
|
|
||||||
if (se.isThisSong)
|
|
||||||
itsSong = se.itsSong;
|
|
||||||
else if (se.itsBuffer)
|
|
||||||
itsBuffer = new NC::Buffer(*se.itsBuffer);
|
|
||||||
else
|
|
||||||
itsBuffer = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isThisSong;
|
|
||||||
|
|
||||||
NC::Buffer *itsBuffer;
|
|
||||||
MPD::Song itsSong;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SearchEngine: Screen<NC::Menu<SEItem>>, Filterable, HasSongs, Searchable, Tabbable
|
|
||||||
{
|
{
|
||||||
SearchEngine();
|
SearchEngine();
|
||||||
|
|
||||||
@@ -135,6 +89,52 @@ private:
|
|||||||
static bool MatchToPattern;
|
static bool MatchToPattern;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SEItem
|
||||||
|
{
|
||||||
|
SEItem() : m_is_song(false), m_buffer(0) { }
|
||||||
|
SEItem(NC::Buffer *buf) : m_is_song(false), m_buffer(buf) { }
|
||||||
|
SEItem(const MPD::Song &s) : m_is_song(true), m_song(s) { }
|
||||||
|
SEItem(const SEItem &ei) { *this = ei; }
|
||||||
|
~SEItem() {
|
||||||
|
if (!m_is_song)
|
||||||
|
delete m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
NC::Buffer &mkBuffer() {
|
||||||
|
assert(!m_is_song);
|
||||||
|
delete m_buffer;
|
||||||
|
m_buffer = new NC::Buffer();
|
||||||
|
return *m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSong() const { return m_is_song; }
|
||||||
|
|
||||||
|
NC::Buffer &buffer() { assert(!m_is_song && m_buffer); return *m_buffer; }
|
||||||
|
MPD::Song &song() { assert(m_is_song); return m_song; }
|
||||||
|
|
||||||
|
const NC::Buffer &buffer() const { assert(!m_is_song && m_buffer); return *m_buffer; }
|
||||||
|
const MPD::Song &song() const { assert(m_is_song); return m_song; }
|
||||||
|
|
||||||
|
SEItem &operator=(const SEItem &se) {
|
||||||
|
if (this == &se)
|
||||||
|
return *this;
|
||||||
|
m_is_song = se.m_is_song;
|
||||||
|
if (se.m_is_song)
|
||||||
|
m_song = se.m_song;
|
||||||
|
else if (se.m_buffer)
|
||||||
|
m_buffer = new NC::Buffer(*se.m_buffer);
|
||||||
|
else
|
||||||
|
m_buffer = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_is_song;
|
||||||
|
|
||||||
|
NC::Buffer *m_buffer;
|
||||||
|
MPD::Song m_song;
|
||||||
|
};
|
||||||
|
|
||||||
extern SearchEngine *mySearcher;
|
extern SearchEngine *mySearcher;
|
||||||
|
|
||||||
#endif // NCMPCPP_SEARCH_ENGINE_H
|
#endif // NCMPCPP_SEARCH_ENGINE_H
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "statusbar.h"
|
#include "statusbar.h"
|
||||||
#include "utility/comparators.h"
|
#include "utility/comparators.h"
|
||||||
#include "screen_switcher.h"
|
#include "screen_switcher.h"
|
||||||
|
#include "charset.h"
|
||||||
|
|
||||||
SelectedItemsAdder *mySelectedItemsAdder;
|
SelectedItemsAdder *mySelectedItemsAdder;
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ namespace {//
|
|||||||
|
|
||||||
void DisplayComponent(SelectedItemsAdder::Component &menu)
|
void DisplayComponent(SelectedItemsAdder::Component &menu)
|
||||||
{
|
{
|
||||||
menu << menu.drawn()->value().item();
|
menu << Charset::utf8ToLocale(menu.drawn()->value().item());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "charset.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@@ -43,7 +44,7 @@ SortPlaylistDialog::SortPlaylistDialog()
|
|||||||
w.cyclicScrolling(Config.use_cyclic_scrolling);
|
w.cyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
w.centeredCursor(Config.centered_cursor);
|
w.centeredCursor(Config.centered_cursor);
|
||||||
w.setItemDisplayer([](Self::WindowType &menu) {
|
w.setItemDisplayer([](Self::WindowType &menu) {
|
||||||
menu << menu.drawn()->value().item().first;
|
menu << Charset::utf8ToLocale(menu.drawn()->value().item().first);
|
||||||
});
|
});
|
||||||
|
|
||||||
w.addItem(Entry(std::make_pair("Artist", &MPD::Song::getArtist),
|
w.addItem(Entry(std::make_pair("Artist", &MPD::Song::getArtist),
|
||||||
|
|||||||
@@ -94,13 +94,17 @@ TagEditor::TagEditor() : FParser(0), FParserHelper(0), FParserLegend(0), FParser
|
|||||||
Dirs->setHighlightColor(Config.active_column_color);
|
Dirs->setHighlightColor(Config.active_column_color);
|
||||||
Dirs->cyclicScrolling(Config.use_cyclic_scrolling);
|
Dirs->cyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Dirs->centeredCursor(Config.centered_cursor);
|
Dirs->centeredCursor(Config.centered_cursor);
|
||||||
Dirs->setItemDisplayer(Display::Pair<std::string, std::string>);
|
Dirs->setItemDisplayer([](NC::Menu<std::pair<std::string, std::string>> &menu) {
|
||||||
|
menu << Charset::utf8ToLocale(menu.drawn()->value().first);
|
||||||
|
});
|
||||||
|
|
||||||
TagTypes = new NC::Menu<std::string>(MiddleColumnStartX, MainStartY, MiddleColumnWidth, MainHeight, Config.titles_visibility ? "Tag types" : "", Config.main_color, NC::brNone);
|
TagTypes = new NC::Menu<std::string>(MiddleColumnStartX, MainStartY, MiddleColumnWidth, MainHeight, Config.titles_visibility ? "Tag types" : "", Config.main_color, NC::brNone);
|
||||||
TagTypes->setHighlightColor(Config.main_highlight_color);
|
TagTypes->setHighlightColor(Config.main_highlight_color);
|
||||||
TagTypes->cyclicScrolling(Config.use_cyclic_scrolling);
|
TagTypes->cyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
TagTypes->centeredCursor(Config.centered_cursor);
|
TagTypes->centeredCursor(Config.centered_cursor);
|
||||||
TagTypes->setItemDisplayer(Display::Default<std::string>);
|
TagTypes->setItemDisplayer([](NC::Menu<std::string> &menu) {
|
||||||
|
menu << Charset::utf8ToLocale(menu.drawn()->value());
|
||||||
|
});
|
||||||
|
|
||||||
for (const SongInfo::Metadata *m = SongInfo::Tags; m->Name; ++m)
|
for (const SongInfo::Metadata *m = SongInfo::Tags; m->Name; ++m)
|
||||||
TagTypes->addItem(m->Name);
|
TagTypes->addItem(m->Name);
|
||||||
@@ -124,10 +128,14 @@ TagEditor::TagEditor() : FParser(0), FParserHelper(0), FParserLegend(0), FParser
|
|||||||
Tags->setSelectedSuffix(Config.selected_item_suffix);
|
Tags->setSelectedSuffix(Config.selected_item_suffix);
|
||||||
Tags->setItemDisplayer(Display::Tags);
|
Tags->setItemDisplayer(Display::Tags);
|
||||||
|
|
||||||
|
auto parser_display = [](NC::Menu<std::string> &menu) {
|
||||||
|
menu << Charset::utf8ToLocale(menu.drawn()->value());
|
||||||
|
};
|
||||||
|
|
||||||
FParserDialog = new NC::Menu<std::string>((COLS-FParserDialogWidth)/2, (MainHeight-FParserDialogHeight)/2+MainStartY, FParserDialogWidth, FParserDialogHeight, "", Config.main_color, Config.window_border);
|
FParserDialog = new NC::Menu<std::string>((COLS-FParserDialogWidth)/2, (MainHeight-FParserDialogHeight)/2+MainStartY, FParserDialogWidth, FParserDialogHeight, "", Config.main_color, Config.window_border);
|
||||||
FParserDialog->cyclicScrolling(Config.use_cyclic_scrolling);
|
FParserDialog->cyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
FParserDialog->centeredCursor(Config.centered_cursor);
|
FParserDialog->centeredCursor(Config.centered_cursor);
|
||||||
FParserDialog->setItemDisplayer(Display::Default<std::string>);
|
FParserDialog->setItemDisplayer(parser_display);
|
||||||
FParserDialog->addItem("Get tags from filename");
|
FParserDialog->addItem("Get tags from filename");
|
||||||
FParserDialog->addItem("Rename files");
|
FParserDialog->addItem("Rename files");
|
||||||
FParserDialog->addSeparator();
|
FParserDialog->addSeparator();
|
||||||
@@ -136,7 +144,7 @@ TagEditor::TagEditor() : FParser(0), FParserHelper(0), FParserLegend(0), FParser
|
|||||||
FParser = new NC::Menu<std::string>((COLS-FParserWidth)/2, (MainHeight-FParserHeight)/2+MainStartY, FParserWidthOne, FParserHeight, "_", Config.main_color, Config.active_window_border);
|
FParser = new NC::Menu<std::string>((COLS-FParserWidth)/2, (MainHeight-FParserHeight)/2+MainStartY, FParserWidthOne, FParserHeight, "_", Config.main_color, Config.active_window_border);
|
||||||
FParser->cyclicScrolling(Config.use_cyclic_scrolling);
|
FParser->cyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
FParser->centeredCursor(Config.centered_cursor);
|
FParser->centeredCursor(Config.centered_cursor);
|
||||||
FParser->setItemDisplayer(Display::Default<std::string>);
|
FParser->setItemDisplayer(parser_display);
|
||||||
|
|
||||||
FParserLegend = new NC::Scrollpad((COLS-FParserWidth)/2+FParserWidthOne, (MainHeight-FParserHeight)/2+MainStartY, FParserWidthTwo, FParserHeight, "Legend", Config.main_color, Config.window_border);
|
FParserLegend = new NC::Scrollpad((COLS-FParserWidth)/2+FParserWidthOne, (MainHeight-FParserHeight)/2+MainStartY, FParserWidthTwo, FParserHeight, "Legend", Config.main_color, Config.window_border);
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ TinyTagEditor::TinyTagEditor()
|
|||||||
w.setHighlightColor(Config.main_highlight_color);
|
w.setHighlightColor(Config.main_highlight_color);
|
||||||
w.cyclicScrolling(Config.use_cyclic_scrolling);
|
w.cyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
w.centeredCursor(Config.centered_cursor);
|
w.centeredCursor(Config.centered_cursor);
|
||||||
w.setItemDisplayer(Display::Default<NC::Buffer>);
|
w.setItemDisplayer([](NC::Menu<NC::Buffer> &menu) {
|
||||||
|
menu << menu.drawn()->value();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void TinyTagEditor::resize()
|
void TinyTagEditor::resize()
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ int LocaleStringComparison::operator()(const std::string &a, const std::string &
|
|||||||
if (hasTheWord(b))
|
if (hasTheWord(b))
|
||||||
bc_off += 4;
|
bc_off += 4;
|
||||||
}
|
}
|
||||||
return std::use_facet< std::collate<char> >(m_locale).compare(
|
return std::use_facet<std::collate<char>>(m_locale).compare(
|
||||||
ac+ac_off, ac+a.length(), bc+bc_off, bc+b.length()
|
ac+ac_off, ac+a.length(), bc+bc_off, bc+b.length()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user