From 0d9aea79c263ce28b3e9d17fb9b620b6bfae4f7a Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Sun, 11 Jan 2009 15:36:14 +0100 Subject: convert id3 tags, directories and playlist names to current locale if needed notice: this feature needs unicode disabled. --- src/Makefile.am | 11 ++-- src/browser.cpp | 5 ++ src/charset.cpp | 150 +++++++++++++++++++++++++++++++++++++++++++++++++ src/charset.h | 53 +++++++++++++++++ src/helpers.cpp | 3 + src/ncmpcpp.cpp | 131 ++++++++++++++++++++++++++++++++---------- src/song.cpp | 65 +++++++++++++++++++-- src/song.h | 7 ++- src/status_checker.cpp | 9 ++- 9 files changed, 390 insertions(+), 44 deletions(-) create mode 100644 src/charset.cpp create mode 100644 src/charset.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 05f98174..d6fb83b6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,12 +1,13 @@ bin_PROGRAMS = ncmpcpp -ncmpcpp_SOURCES = browser.cpp help.cpp helpers.cpp libmpdclient.c lyrics.cpp \ - misc.cpp mpdpp.cpp ncmpcpp.cpp scrollpad.cpp search_engine.cpp settings.cpp \ - song.cpp status_checker.cpp str_pool.c tag_editor.cpp window.cpp +ncmpcpp_SOURCES = browser.cpp charset.cpp help.cpp helpers.cpp libmpdclient.c \ + lyrics.cpp misc.cpp mpdpp.cpp ncmpcpp.cpp scrollpad.cpp search_engine.cpp \ + settings.cpp song.cpp status_checker.cpp str_pool.c tag_editor.cpp window.cpp # set the include path found by configure INCLUDES= $(all_includes) # the library search path. ncmpcpp_LDFLAGS = $(all_libraries) -noinst_HEADERS = browser.h help.h helpers.h lyrics.h menu.h mpdpp.h scrollpad.h \ - search_engine.h settings.h song.h status_checker.h tag_editor.h window.h +noinst_HEADERS = browser.h charset.h help.h helpers.h lyrics.h menu.h mpdpp.h \ + scrollpad.h search_engine.h settings.h song.h status_checker.h tag_editor.h \ + window.h diff --git a/src/browser.cpp b/src/browser.cpp index 5583d4e6..7b50f6ea 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -23,6 +23,7 @@ #include #include "browser.h" +#include "charset.h" #include "helpers.h" #include "settings.h" #ifdef HAVE_TAGLIB_H @@ -163,6 +164,8 @@ void GetDirectory(string dir, string subdir) mBrowser->Reset(); browsed_dir = dir; + locale_to_utf(dir); + for (size_t i = 0; i < mBrowser->Size(); i++) if (mBrowser->at(i).song != (void *)1) delete mBrowser->at(i).song; @@ -189,11 +192,13 @@ void GetDirectory(string dir, string subdir) { case itPlaylist: { + utf_to_locale(it->name); mBrowser->AddOption(*it); break; } case itDirectory: { + utf_to_locale(it->name); if (it->name == subdir) highlightme = mBrowser->Size(); mBrowser->AddOption(*it); diff --git a/src/charset.cpp b/src/charset.cpp new file mode 100644 index 00000000..c82af514 --- /dev/null +++ b/src/charset.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + * Copyright (C) 2008 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "charset.h" + +#if !defined(_UTF8) && defined(HAVE_ICONV_H) + +#include +#include +#include +#include +#include + +#include "locale.h" +#include "str_pool.h" + +namespace +{ + char *locale_charset = 0; + + bool has_non_ascii_chars(const char *s) + { + for (; s; s++) + if (*s < 0) + return true; + return false; + } + + bool has_non_ascii_chars(const std::string &s) + { + for (std::string::const_iterator it = s.begin(); it != s.end(); it++) + if (*it < 0) + return true; + return false; + } + + void charset_convert(const char *from, const char *to, char *&inbuf, size_t len = 0) + { + if (!inbuf || !from || !to) + return; + + iconv_t cd = iconv_open(to, from); + + if (cd == (iconv_t)-1) + return; + + if (!len) + len = strlen(inbuf); + size_t buflen = len*6+1; + char *outbuf = new char[buflen]; + memset(outbuf, 0, sizeof(char)*buflen); + char *outstart = outbuf; + char *instart = inbuf; + + if (iconv(cd, &inbuf, &len, &outbuf, &buflen) == (size_t)-1) + { + delete [] outstart; + iconv_close(cd); + return; + } + iconv_close(cd); + + str_pool_put(instart); + inbuf = str_pool_get(outstart); + delete [] outstart; + } +} + +void init_current_locale() +{ + std::string envlocale = getenv("LC_CTYPE") ? getenv("LC_CTYPE") : (getenv("LC_ALL") ? getenv("LC_ALL") : ""); + if (envlocale.empty()) + return; + std::ifstream f(SUPPORTED_LOCALES); + if (!f.is_open()) + return; + envlocale += " "; + std::string line; + while (!f.eof()) + { + getline(f, line); + if (line.find(envlocale) != std::string::npos) + { + try + { + locale_charset = strdup((line.substr(line.find(" ")+1) + "//TRANSLIT").c_str()); + } + catch (std::out_of_range) + { + return; + } + break; + } + } + f.close(); +} + +void utf_to_locale(std::string &s) +{ + if (s.empty() || !locale_charset || !has_non_ascii_chars(s)) + return; + char *tmp = str_pool_get(s.c_str()); + charset_convert("utf8", locale_charset, tmp, s.length()); + s = tmp; + str_pool_put(tmp); +} + +void locale_to_utf(std::string &s) +{ + if (s.empty() || !locale_charset || !has_non_ascii_chars(s)) + return; + char *tmp = str_pool_get(s.c_str()); + charset_convert(locale_charset, "utf8", tmp, s.length()); + s = tmp; + str_pool_put(tmp); +} + +void str_pool_utf_to_locale(char *&s) +{ + if (!has_non_ascii_chars(s)) + return; + charset_convert("utf8", locale_charset, s); +} + +void str_pool_locale_to_utf(char *&s) +{ + if (!has_non_ascii_chars(s)) + return; + charset_convert(locale_charset, "utf8", s); +} + +#endif + diff --git a/src/charset.h b/src/charset.h new file mode 100644 index 00000000..b6c98375 --- /dev/null +++ b/src/charset.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2008 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _CHARSET_H +#define _CHARSET_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if !defined(_UTF8) && defined(HAVE_ICONV_H) + +#include + +void init_current_locale(); + +void utf_to_locale(std::string &); +void locale_to_utf(std::string &); + +void str_pool_utf_to_locale(char *&); +void str_pool_locale_to_utf(char *&); + +#else + +#define init_current_locale(); + +#define utf_to_locale(x); +#define locale_to_utf(x); + +#define str_pool_utf_to_locale(x); +#define str_pool_locale_to_utf(x); + +#endif // !_UTF8 && HAVE_ICONV_H + +#endif + diff --git a/src/helpers.cpp b/src/helpers.cpp index 1743473d..143ebbe8 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -21,6 +21,7 @@ #include #include +#include "charset.h" #include "helpers.h" #include "tag_editor.h" @@ -532,6 +533,8 @@ void DisplaySongInColumns(const Song &s, void *s_template, Menu *menu) void DisplaySong(const Song &s, void *data, Menu *menu) { + const_cast(&s)->LocalizeTags(); + const string &song_template = data ? *static_cast(data) : ""; basic_buffer buf; bool right = 0; diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index e6bc46e2..4523965b 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -30,6 +30,7 @@ #include "ncmpcpp.h" #include "browser.h" +#include "charset.h" #include "help.h" #include "helpers.h" #include "lyrics.h" @@ -193,6 +194,7 @@ int main(int argc, char *argv[]) return -1; InitScreen(Config.colors_enabled); + init_current_locale(); size_t main_start_y = 2; size_t main_height = LINES-4; @@ -484,7 +486,10 @@ int main(int argc, char *argv[]) for (TagList::iterator it = list.begin(); it != list.end(); it++) { if (!it->empty()) + { + utf_to_locale(*it); mLibArtists->AddOption(*it); + } } mLibArtists->Window::Clear(); mLibArtists->Refresh(); @@ -495,6 +500,7 @@ int main(int argc, char *argv[]) mLibAlbums->Reset(); TagList list; std::map maplist; + locale_to_utf(mLibArtists->Current()); if (Config.media_lib_primary_tag == MPD_TAG_ITEM_ARTIST) Mpd->GetAlbums(mLibArtists->Current(), list); else @@ -504,7 +510,7 @@ int main(int argc, char *argv[]) Mpd->StartFieldSearch(MPD_TAG_ITEM_ALBUM); Mpd->CommitSearch(list); } - for (TagList::const_iterator it = list.begin(); it != list.end(); it++) + for (TagList::iterator it = list.begin(); it != list.end(); it++) { SongList l; Mpd->StartSearch(1); @@ -512,9 +518,14 @@ int main(int argc, char *argv[]) Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, *it); Mpd->CommitSearch(l); if (!l.empty() && !l[0]->GetAlbum().empty()) + { + utf_to_locale(*it); + l[0]->LocalizeTags(); maplist[l[0]->toString(Config.media_lib_album_format)] = *it; + } FreeSongList(l); } + utf_to_locale(mLibArtists->Current()); for (std::map::const_iterator it = maplist.begin(); it != maplist.end(); it++) mLibAlbums->AddOption(make_pair(it->first, it->second)); mLibAlbums->Window::Clear(); @@ -538,7 +549,9 @@ int main(int argc, char *argv[]) mLibAlbums->Refresh(); mLibSongs->Clear(0); Mpd->StartSearch(1); + locale_to_utf(mLibArtists->Current()); Mpd->AddSearch(Config.media_lib_primary_tag, mLibArtists->Current()); + utf_to_locale(mLibArtists->Current()); Mpd->CommitSearch(list); } else @@ -546,7 +559,9 @@ int main(int argc, char *argv[]) mLibSongs->Clear(0); Mpd->StartSearch(1); Mpd->AddSearch(Config.media_lib_primary_tag, mLibArtists->Current()); + locale_to_utf(mLibAlbums->Current().second); Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, mLibAlbums->Current().second); + utf_to_locale(mLibAlbums->Current().second); Mpd->CommitSearch(list); } sort(list.begin(), list.end(), SortSongsByTrack); @@ -581,7 +596,10 @@ int main(int argc, char *argv[]) TagList list; Mpd->GetPlaylists(list); for (TagList::iterator it = list.begin(); it != list.end(); it++) + { + utf_to_locale(*it); mPlaylistList->AddOption(*it); + } mPlaylistList->Window::Clear(); mPlaylistList->Refresh(); } @@ -590,7 +608,9 @@ int main(int argc, char *argv[]) { mPlaylistEditor->Reset(); SongList list; + locale_to_utf(mPlaylistList->Current()); Mpd->GetPlaylistContent(mPlaylistList->Current(), list); + utf_to_locale(mPlaylistList->Current()); if (!list.empty()) mPlaylistEditor->SetTitle("Playlist's content (" + IntoStr(list.size()) + " item" + (list.size() == 1 ? ")" : "s)")); else @@ -651,7 +671,10 @@ int main(int argc, char *argv[]) Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, *it); Mpd->CommitSearch(l); if (!l.empty()) + { + l[0]->LocalizeTags(); maplist[l[0]->toString(Config.tag_editor_album_format)] = *it; + } FreeSongList(l); } for (std::map::const_iterator it = maplist.begin(); it != maplist.end(); it++) @@ -676,6 +699,7 @@ int main(int argc, char *argv[]) { size_t slash = it->find_last_of("/"); string to_display = slash != string::npos ? it->substr(slash+1) : *it; + utf_to_locale(to_display); mEditorDirs->AddOption(make_pair(to_display, *it)); if (*it == editor_highlighted_dir) highlightme = mEditorDirs->Size()-1; @@ -698,14 +722,20 @@ int main(int argc, char *argv[]) Mpd->CommitSearch(list); sort(list.begin(), list.end(), CaseInsensitiveSorting()); for (SongList::iterator it = list.begin(); it != list.end(); it++) + { + (*it)->LocalizeTags(); mEditorTags->AddOption(**it); + } } else { Mpd->GetSongs(mEditorDirs->Current().second, list); sort(list.begin(), list.end(), CaseInsensitiveSorting()); for (SongList::const_iterator it = list.begin(); it != list.end(); it++) + { + (*it)->LocalizeTags(); mEditorTags->AddOption(**it); + } } FreeSongList(list); mEditorTags->Window::Clear(); @@ -992,7 +1022,9 @@ int main(int argc, char *argv[]) case itPlaylist: { SongList list; - Mpd->GetPlaylistContent(item.name, list); + string playlist_real_name = item.name; + locale_to_utf(playlist_real_name); + Mpd->GetPlaylistContent(playlist_real_name, list); for (SongList::const_iterator it = list.begin(); it != list.end(); it++) Mpd->QueueAddSong(**it); if (Mpd->CommitQueue()) @@ -1311,7 +1343,8 @@ int main(int argc, char *argv[]) if (!mLibArtists->Empty() && wCurrent == mLibArtists) { - const string &tag = mLibArtists->Current(); + string tag = mLibArtists->Current(); + locale_to_utf(tag); Mpd->StartSearch(1); Mpd->AddSearch(Config.media_lib_primary_tag, tag); Mpd->CommitSearch(list); @@ -1321,7 +1354,7 @@ int main(int argc, char *argv[]) { string tag_type = IntoStr(Config.media_lib_primary_tag); ToLower(tag_type); - ShowMessage("Adding songs of %s \"%s\"", tag_type.c_str(), tag.c_str()); + ShowMessage("Adding songs of %s \"%s\"", tag_type.c_str(), mLibArtists->Current().c_str()); Song *s = &mPlaylist->at(mPlaylist->Size()-list.size()); if (s->GetHash() == list[0]->GetHash()) { @@ -1420,13 +1453,14 @@ int main(int argc, char *argv[]) if (wCurrent == mPlaylistList && !mPlaylistList->Empty()) { - const string &playlist = mPlaylistList->Current(); + string playlist = mPlaylistList->Current(); + locale_to_utf(playlist); Mpd->GetPlaylistContent(playlist, list); for (SongList::const_iterator it = list.begin(); it != list.end(); it++) Mpd->QueueAddSong(**it); if (Mpd->CommitQueue()) { - ShowMessage("Loading playlist %s...", playlist.c_str()); + ShowMessage("Loading playlist %s...", mPlaylistList->Current().c_str()); Song &s = mPlaylist->at(mPlaylist->Size()-list.size()); if (s.GetHash() == list[0]->GetHash()) { @@ -1714,8 +1748,11 @@ int main(int argc, char *argv[]) if (browsed_dir != "/" && !mBrowser->Choice()) continue; // do not let add parent dir. + string real_dir_name = item.name; + locale_to_utf(real_dir_name); + SongList list; - Mpd->GetDirectoryRecursive(item.name, list); + Mpd->GetDirectoryRecursive(real_dir_name, list); for (SongList::const_iterator it = list.begin(); it != list.end(); it++) Mpd->QueueAddSong(**it); @@ -1762,7 +1799,9 @@ int main(int argc, char *argv[]) case itPlaylist: { SongList list; - Mpd->GetPlaylistContent(item.name, list); + string playlist_real_name = item.name; + locale_to_utf(playlist_real_name); + Mpd->GetPlaylistContent(playlist_real_name, list); for (SongList::const_iterator it = list.begin(); it != list.end(); it++) Mpd->QueueAddSong(**it); if (Mpd->CommitQueue()) @@ -1986,7 +2025,7 @@ int main(int argc, char *argv[]) else if (current_screen == csBrowser || wCurrent == mPlaylistList) { LockStatusbar(); - const string &name = wCurrent == mBrowser ? mBrowser->Current().name : mPlaylistList->Current(); + string name = wCurrent == mBrowser ? mBrowser->Current().name : mPlaylistList->Current(); if (current_screen != csBrowser || mBrowser->Current().type == itPlaylist) { Statusbar() << "Delete playlist " << name << " ? [y/n] "; @@ -2000,7 +2039,9 @@ int main(int argc, char *argv[]) while (in != 'y' && in != 'n'); if (in == 'y') { + locale_to_utf(name); Mpd->DeletePlaylist(name); + utf_to_locale(name); ShowMessage("Playlist %s deleted!", name.c_str()); if (!Config.local_browser) GetDirectory("/"); @@ -2018,17 +2059,20 @@ int main(int argc, char *argv[]) { vector list; mPlaylistEditor->GetSelected(list); + locale_to_utf(mPlaylistList->Current()); for (vector::const_reverse_iterator it = list.rbegin(); it != ((const vector &)list).rend(); it++) { Mpd->QueueDeleteFromPlaylist(mPlaylistList->Current(), *it); mPlaylistEditor->DeleteOption(*it); } + utf_to_locale(mPlaylistList->Current()); ShowMessage("Selected items deleted from playlist '%s'!", mPlaylistList->Current().c_str()); // redraw_screen = 1; } else { mPlaylistEditor->SetTimeout(50); + locale_to_utf(mPlaylistList->Current()); while (!mPlaylistEditor->Empty() && Keypressed(input, Key.Delete)) { TraceMpdStatus(); @@ -2038,6 +2082,7 @@ int main(int argc, char *argv[]) mPlaylistEditor->Refresh(); mPlaylistEditor->ReadKey(input); } + utf_to_locale(mPlaylistList->Current()); mPlaylistEditor->SetTimeout(ncmpcpp_window_timeout); } Mpd->CommitQueue(); @@ -2060,6 +2105,8 @@ int main(int argc, char *argv[]) LockStatusbar(); Statusbar() << "Save playlist as: "; string playlist_name = wFooter->GetString(); + string real_playlist_name = playlist_name; + locale_to_utf(real_playlist_name); UnlockStatusbar(); if (playlist_name.find("/") != string::npos) { @@ -2068,7 +2115,7 @@ int main(int argc, char *argv[]) } if (!playlist_name.empty()) { - if (Mpd->SavePlaylist(playlist_name)) + if (Mpd->SavePlaylist(real_playlist_name)) { ShowMessage("Playlist saved as: %s", playlist_name.c_str()); mPlaylistList->Clear(0); // make playlist's list update itself @@ -2089,8 +2136,8 @@ int main(int argc, char *argv[]) if (in == 'y') { - Mpd->DeletePlaylist(playlist_name); - if (Mpd->SavePlaylist(playlist_name)) + Mpd->DeletePlaylist(real_playlist_name); + if (Mpd->SavePlaylist(real_playlist_name)) ShowMessage("Playlist overwritten!"); } else @@ -2474,13 +2521,16 @@ int main(int argc, char *argv[]) SongList list; ShowMessage("Updating tags..."); Mpd->StartSearch(1); + locale_to_utf(mLibArtists->Current()); Mpd->AddSearch(Config.media_lib_primary_tag, mLibArtists->Current()); + utf_to_locale(mLibArtists->Current()); Mpd->CommitSearch(list); SongSetFunction set = IntoSetFunction(Config.media_lib_primary_tag); if (!set) continue; - for (SongList::const_iterator it = list.begin(); it != list.end(); it++) + for (SongList::iterator it = list.begin(); it != list.end(); it++) { + (*it)->LocalizeTags(); ((*it)->*set)(new_tag); ShowMessage("Updating tags in '%s'...", (*it)->GetName().c_str()); string path = Config.mpd_music_dir + (*it)->GetFile(); @@ -2508,20 +2558,16 @@ int main(int argc, char *argv[]) if (!new_album.empty() && new_album != mLibAlbums->Current().second) { bool success = 1; - SongList list; ShowMessage("Updating tags..."); - Mpd->StartSearch(1); - Mpd->AddSearch(Config.media_lib_primary_tag, mLibArtists->Current()); - Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, mLibAlbums->Current().second); - Mpd->CommitSearch(list); - for (SongList::const_iterator it = list.begin(); it != list.end(); it++) + for (size_t i = 0; i < mLibSongs->Size(); i++) { - ShowMessage("Updating tags in '%s'...", (*it)->GetName().c_str()); - string path = Config.mpd_music_dir + (*it)->GetFile(); + (*mLibSongs)[i].LocalizeTags(); + ShowMessage("Updating tags in '%s'...", (*mLibSongs)[i].GetName().c_str()); + string path = Config.mpd_music_dir + (*mLibSongs)[i].GetFile(); TagLib::FileRef f(path.c_str()); if (f.isNull()) { - ShowMessage("Error updating tags in '%s'!", (*it)->GetFile().c_str()); + ShowMessage("Error updating tags in '%s'!", (*mLibSongs)[i].GetFile().c_str()); success = 0; break; } @@ -2530,10 +2576,9 @@ int main(int argc, char *argv[]) } if (success) { - Mpd->UpdateDirectory(FindSharedDir(list)); + Mpd->UpdateDirectory(FindSharedDir(mLibSongs)); ShowMessage("Tags updated succesfully!"); } - FreeSongList(list); } } else if ( @@ -2600,15 +2645,20 @@ int main(int argc, char *argv[]) UnlockStatusbar(); if (!new_dir.empty() && new_dir != old_dir) { + locale_to_utf(old_dir); + locale_to_utf(new_dir); string full_old_dir = Config.mpd_music_dir + editor_browsed_dir + "/" + old_dir; string full_new_dir = Config.mpd_music_dir + editor_browsed_dir + "/" + new_dir; if (rename(full_old_dir.c_str(), full_new_dir.c_str()) == 0) { Mpd->UpdateDirectory(editor_browsed_dir); - ShowMessage("'%s' renamed to '%s'", old_dir.c_str(), new_dir.c_str()); } else - ShowMessage("Cannot rename '%s' to '%s'!", full_old_dir.c_str(), full_new_dir.c_str()); + { + utf_to_locale(old_dir); + utf_to_locale(new_dir); + ShowMessage("Cannot rename '%s' to '%s'!", old_dir.c_str(), new_dir.c_str()); + } } } else @@ -2622,6 +2672,8 @@ int main(int argc, char *argv[]) UnlockStatusbar(); if (!new_dir.empty() && new_dir != old_dir) { + locale_to_utf(old_dir); + locale_to_utf(new_dir); string full_old_dir; if (!Config.local_browser) full_old_dir += Config.mpd_music_dir; @@ -2630,7 +2682,10 @@ int main(int argc, char *argv[]) if (!Config.local_browser) full_new_dir += Config.mpd_music_dir; full_new_dir += new_dir; - if (rename(full_old_dir.c_str(), full_new_dir.c_str()) == 0) + int rename_result = rename(full_old_dir.c_str(), full_new_dir.c_str()); + utf_to_locale(old_dir); + utf_to_locale(new_dir); + if (rename_result == 0) { ShowMessage("'%s' renamed to '%s'", old_dir.c_str(), new_dir.c_str()); if (!Config.local_browser) @@ -2638,7 +2693,7 @@ int main(int argc, char *argv[]) GetDirectory(browsed_dir); } else - ShowMessage("Cannot rename '%s' to '%s'!", full_old_dir.c_str(), full_new_dir.c_str()); + ShowMessage("Cannot rename '%s' to '%s'!", old_dir.c_str(), new_dir.c_str()); } } else if (wCurrent == mPlaylistList || (wCurrent == mBrowser && mBrowser->Current().type == itPlaylist)) @@ -2650,7 +2705,11 @@ int main(int argc, char *argv[]) UnlockStatusbar(); if (!new_name.empty() && new_name != old_name) { + locale_to_utf(old_name); + locale_to_utf(new_name); Mpd->Rename(old_name, new_name); + utf_to_locale(old_name); + utf_to_locale(new_name); ShowMessage("Playlist '%s' renamed to '%s'", old_name.c_str(), new_name.c_str()); if (!Config.local_browser) GetDirectory("/"); @@ -2695,7 +2754,10 @@ int main(int argc, char *argv[]) Config.local_browser = !s->IsFromDB(); string option = s->toString(Config.song_status_format); - GetDirectory(s->GetDirectory()); + string localed_dir = s->GetDirectory(); + locale_to_utf(option); + utf_to_locale(localed_dir); + GetDirectory(localed_dir); for (size_t i = 0; i < mBrowser->Size(); i++) { if (mBrowser->at(i).type == itSong && option == mBrowser->at(i).song->toString(Config.song_status_format)) @@ -2852,8 +2914,11 @@ int main(int argc, char *argv[]) mDialog->AddSeparator(); TagList playlists; Mpd->GetPlaylists(playlists); - for (TagList::const_iterator it = playlists.begin(); it != playlists.end(); it++) + for (TagList::iterator it = playlists.begin(); it != playlists.end(); it++) + { + utf_to_locale(*it); mDialog->AddOption("'" + *it + "' playlist"); + } mDialog->AddSeparator(); mDialog->AddOption("Cancel"); @@ -2912,20 +2977,24 @@ int main(int argc, char *argv[]) LockStatusbar(); Statusbar() << "Save playlist as: "; string playlist = wFooter->GetString(); + string real_playlist = playlist; + locale_to_utf(real_playlist); UnlockStatusbar(); if (!playlist.empty()) { for (SongList::const_iterator it = result.begin(); it != result.end(); it++) - Mpd->QueueAddToPlaylist(playlist, **it); + Mpd->QueueAddToPlaylist(real_playlist, **it); Mpd->CommitQueue(); ShowMessage("Selected items added to playlist '%s'!", playlist.c_str()); } } else if (id > 1 && id < mDialog->Size()-1) { + locale_to_utf(playlists[id-3]); for (SongList::const_iterator it = result.begin(); it != result.end(); it++) Mpd->QueueAddToPlaylist(playlists[id-3], **it); Mpd->CommitQueue(); + utf_to_locale(playlists[id-3]); ShowMessage("Selected items added to playlist '%s'!", playlists[id-3].c_str()); } diff --git a/src/song.cpp b/src/song.cpp index b01eb10b..5a819aed 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -18,6 +18,11 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "charset.h" #include "song.h" #include "settings.h" @@ -25,15 +30,14 @@ Song::Song(mpd_Song *s, bool copy_ptr) : itsSong(s), itsSlash(string::npos), itsHash(0), copyPtr(copy_ptr), - isStream(0) + isStream(0), + isLocalised(0) { size_t file_len = itsSong->file ? strlen(itsSong->file) : 0; if (itsSong->file) { - char *tmp = strrchr(itsSong->file, '/'); - if (tmp) - itsSlash = tmp-itsSong->file; + __Count_Last_Slash_Position(); if (strncmp(itsSong->file, "http://", 7) == 0) isStream = 1; } @@ -52,7 +56,8 @@ Song::Song(const Song &s) : itsSong(0), itsSlash(s.itsSlash), itsHash(s.itsHash), copyPtr(s.copyPtr), - isStream(s.isStream) + isStream(s.isStream), + isLocalised(s.isLocalised) { itsSong = s.copyPtr ? s.itsSong : mpd_songDup(s.itsSong); } @@ -70,6 +75,46 @@ string Song::GetLength() const return ShowTime(itsSong->time); } +void Song::LocalizeTags() +{ +# if !defined(_UTF8) && defined(HAVE_ICONV_H) + if (isLocalised) + return; + str_pool_utf_to_locale(itsSong->artist); + str_pool_utf_to_locale(itsSong->title); + str_pool_utf_to_locale(itsSong->album); + str_pool_utf_to_locale(itsSong->track); + str_pool_utf_to_locale(itsSong->name); + str_pool_utf_to_locale(itsSong->date); + str_pool_utf_to_locale(itsSong->genre); + str_pool_utf_to_locale(itsSong->composer); + str_pool_utf_to_locale(itsSong->performer); + str_pool_utf_to_locale(itsSong->disc); + str_pool_utf_to_locale(itsSong->comment); + isLocalised = 1; +# endif // !_UTF8 && HAVE_ICONV_H +} + +void Song::DelocalizeTags() +{ +# if !defined(_UTF8) && defined(HAVE_ICONV_H) + if (!isLocalised) + return; + str_pool_locale_to_utf(itsSong->artist); + str_pool_locale_to_utf(itsSong->title); + str_pool_locale_to_utf(itsSong->album); + str_pool_locale_to_utf(itsSong->track); + str_pool_locale_to_utf(itsSong->name); + str_pool_locale_to_utf(itsSong->date); + str_pool_locale_to_utf(itsSong->genre); + str_pool_locale_to_utf(itsSong->composer); + str_pool_locale_to_utf(itsSong->performer); + str_pool_locale_to_utf(itsSong->disc); + str_pool_locale_to_utf(itsSong->comment); + isLocalised = 0; +# endif // !_UTF8 && HAVE_ICONV_H +} + void Song::Clear() { if (itsSong) @@ -78,6 +123,8 @@ void Song::Clear() itsNewName.clear(); itsSlash = 0; itsHash = 0; + isStream = 0; + isLocalised = 0; copyPtr = 0; } @@ -427,6 +474,7 @@ Song & Song::operator=(const Song &s) itsHash = s.itsHash; copyPtr = s.copyPtr; isStream = s.isStream; + isLocalised = s.isLocalised; return *this; } @@ -505,3 +553,10 @@ string Song::ShowTime(int length) return ss.str(); } +void Song::__Count_Last_Slash_Position() +{ + char *tmp = strrchr(itsSong->file, '/'); + if (tmp) + itsSlash = tmp-itsSong->file; +} + diff --git a/src/song.h b/src/song.h index d5d63b3a..5b6d09ef 100644 --- a/src/song.h +++ b/src/song.h @@ -34,7 +34,7 @@ using std::string; class Song { public: - Song() : itsSlash(string::npos), itsHash(0), copyPtr(0), isStream(0) { itsSong = mpd_newSong(); } + Song() : itsSlash(string::npos), itsHash(0), copyPtr(0), isStream(0), isLocalised(0) { itsSong = mpd_newSong(); } Song(mpd_Song *, bool = 0); Song(const Song &); ~Song(); @@ -82,6 +82,8 @@ class Song void CopyPtr(bool copy) { copyPtr = copy; } //void GetEmptyFields(bool get) { itsGetEmptyFields = get; } + void LocalizeTags(); + void DelocalizeTags(); void Clear(); bool Empty() const; bool IsFromDB() const; @@ -94,12 +96,15 @@ class Song static string ShowTime(int); private: + void __Count_Last_Slash_Position(); + mpd_Song *itsSong; string itsNewName; size_t itsSlash; long long itsHash; bool copyPtr; bool isStream; + bool isLocalised; //bool itsGetEmptyFields; }; diff --git a/src/status_checker.cpp b/src/status_checker.cpp index 2bbea936..0da9a3dc 100644 --- a/src/status_checker.cpp +++ b/src/status_checker.cpp @@ -19,6 +19,7 @@ ***************************************************************************/ #include "browser.h" +#include "charset.h" #include "helpers.h" #include "search_engine.h" #include "settings.h" @@ -338,7 +339,9 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *) if (s.GetTotalLength() && elapsed == s.GetTotalLength()-1) repeat_one_allowed = 1; - WindowTitle(s.toString(Config.song_window_title_format)); + string song_str = s.toString(Config.song_window_title_format); + utf_to_locale(song_str); + WindowTitle(song_str); if (!block_statusbar_update && Config.statusbar_visibility) { @@ -359,7 +362,9 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *) } wFooter->WriteXY(0, 1, 1, "%s", player_state.c_str()); wFooter->Bold(0); - Scroller(*wFooter, s.toString(Config.song_status_format), wFooter->GetWidth()-player_state.length()-tracklength.length(), playing_song_scroll_begin); + song_str = s.toString(Config.song_status_format); + utf_to_locale(song_str); + Scroller(*wFooter, song_str, wFooter->GetWidth()-player_state.length()-tracklength.length(), playing_song_scroll_begin); wFooter->Bold(1); wFooter->WriteXY(wFooter->GetWidth()-tracklength.length(), 1, 1, "%s", tracklength.c_str()); -- cgit v1.2.3