move wstring related functions to wide_char file
This commit is contained in:
@@ -4,6 +4,7 @@ ncmpcpp_SOURCES = \
|
|||||||
utility/html.cpp \
|
utility/html.cpp \
|
||||||
utility/string.cpp \
|
utility/string.cpp \
|
||||||
utility/type_conversions.cpp \
|
utility/type_conversions.cpp \
|
||||||
|
utility/wide_string.cpp \
|
||||||
actions.cpp \
|
actions.cpp \
|
||||||
bindings.cpp \
|
bindings.cpp \
|
||||||
browser.cpp \
|
browser.cpp \
|
||||||
@@ -52,6 +53,7 @@ noinst_HEADERS = \
|
|||||||
utility/string.h \
|
utility/string.h \
|
||||||
utility/numeric_conversions.h \
|
utility/numeric_conversions.h \
|
||||||
utility/type_conversions.h \
|
utility/type_conversions.h \
|
||||||
|
utility/wide_string.h \
|
||||||
bindings.h \
|
bindings.h \
|
||||||
browser.h \
|
browser.h \
|
||||||
charset.h \
|
charset.h \
|
||||||
|
|||||||
@@ -800,7 +800,7 @@ void Delete::Run()
|
|||||||
question = "Delete ";
|
question = "Delete ";
|
||||||
question += itemTypeToString(item.type);
|
question += itemTypeToString(item.type);
|
||||||
question += " \"";
|
question += " \"";
|
||||||
question += Shorten(ToWString(name), COLS-question.size()-10);
|
question += ToString(wideShorten(ToWString(name), COLS-question.size()-10));
|
||||||
question += "\"?";
|
question += "\"?";
|
||||||
}
|
}
|
||||||
bool yes = AskYesNoQuestion(question, TraceMpdStatus);
|
bool yes = AskYesNoQuestion(question, TraceMpdStatus);
|
||||||
@@ -814,13 +814,13 @@ void Delete::Run()
|
|||||||
std::string name = i.type == MPD::itSong ? i.song->getName() : i.name;
|
std::string name = i.type == MPD::itSong ? i.song->getName() : i.name;
|
||||||
if (myBrowser->deleteItem(i))
|
if (myBrowser->deleteItem(i))
|
||||||
{
|
{
|
||||||
const char msg[] = "\"%s\" deleted";
|
const char msg[] = "\"%ls\" deleted";
|
||||||
ShowMessage(msg, Shorten(ToWString(name), COLS-const_strlen(msg)).c_str());
|
ShowMessage(msg, wideShorten(ToWString(name), COLS-const_strlen(msg)).c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char msg[] = "Couldn't delete \"%s\": %s";
|
const char msg[] = "Couldn't delete \"%ls\": %s";
|
||||||
ShowMessage(msg, Shorten(ToWString(name), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
ShowMessage(msg, wideShorten(ToWString(name), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -845,7 +845,7 @@ void Delete::Run()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
question = "Delete playlist \"";
|
question = "Delete playlist \"";
|
||||||
question += Shorten(ToWString(myPlaylistEditor->Playlists->current().value()), COLS-question.size()-10);
|
question += ToString(wideShorten(ToWString(myPlaylistEditor->Playlists->current().value()), COLS-question.size()-10));
|
||||||
question += "\"?";
|
question += "\"?";
|
||||||
}
|
}
|
||||||
bool yes = AskYesNoQuestion(question, TraceMpdStatus);
|
bool yes = AskYesNoQuestion(question, TraceMpdStatus);
|
||||||
@@ -1384,8 +1384,8 @@ void EditLibraryTag::Run()
|
|||||||
std::string path = Config.mpd_music_dir + es.getURI();
|
std::string path = Config.mpd_music_dir + es.getURI();
|
||||||
if (!TagEditor::WriteTags(es))
|
if (!TagEditor::WriteTags(es))
|
||||||
{
|
{
|
||||||
const char msg[] = "Error while updating tags in \"%s\"";
|
const char msg[] = "Error while updating tags in \"%ls\"";
|
||||||
ShowMessage(msg, Shorten(ToWString(es.getURI()), COLS-const_strlen(msg)).c_str());
|
ShowMessage(msg, wideShorten(ToWString(es.getURI()), COLS-const_strlen(msg)).c_str());
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1430,16 +1430,16 @@ void EditLibraryAlbum::Run()
|
|||||||
TagLib::FileRef f(path.c_str());
|
TagLib::FileRef f(path.c_str());
|
||||||
if (f.isNull())
|
if (f.isNull())
|
||||||
{
|
{
|
||||||
const char msg[] = "Error while opening file \"%s\"";
|
const char msg[] = "Error while opening file \"%ls\"";
|
||||||
ShowMessage(msg, Shorten(ToWString((*myLibrary->Songs)[i].value().getURI()), COLS-const_strlen(msg)).c_str());
|
ShowMessage(msg, wideShorten(ToWString((*myLibrary->Songs)[i].value().getURI()), COLS-const_strlen(msg)).c_str());
|
||||||
success = 0;
|
success = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
f.tag()->setAlbum(ToWString(new_album));
|
f.tag()->setAlbum(ToWString(new_album));
|
||||||
if (!f.save())
|
if (!f.save())
|
||||||
{
|
{
|
||||||
const char msg[] = "Error while writing tags in \"%s\"";
|
const char msg[] = "Error while writing tags in \"%ls\"";
|
||||||
ShowMessage(msg, Shorten(ToWString((*myLibrary->Songs)[i].value().getURI()), COLS-const_strlen(msg)).c_str());
|
ShowMessage(msg, wideShorten(ToWString((*myLibrary->Songs)[i].value().getURI()), COLS-const_strlen(msg)).c_str());
|
||||||
success = 0;
|
success = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1491,16 +1491,16 @@ void EditDirectoryName::Run()
|
|||||||
int rename_result = rename(full_old_dir.c_str(), full_new_dir.c_str());
|
int rename_result = rename(full_old_dir.c_str(), full_new_dir.c_str());
|
||||||
if (rename_result == 0)
|
if (rename_result == 0)
|
||||||
{
|
{
|
||||||
const char msg[] = "Directory renamed to \"%s\"";
|
const char msg[] = "Directory renamed to \"%ls\"";
|
||||||
ShowMessage(msg, Shorten(ToWString(new_dir), COLS-const_strlen(msg)).c_str());
|
ShowMessage(msg, wideShorten(ToWString(new_dir), COLS-const_strlen(msg)).c_str());
|
||||||
if (!myBrowser->isLocal())
|
if (!myBrowser->isLocal())
|
||||||
Mpd.UpdateDirectory(locale_to_utf_cpy(getSharedDirectory(old_dir, new_dir)));
|
Mpd.UpdateDirectory(locale_to_utf_cpy(getSharedDirectory(old_dir, new_dir)));
|
||||||
myBrowser->GetDirectory(myBrowser->CurrentDir());
|
myBrowser->GetDirectory(myBrowser->CurrentDir());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char msg[] = "Couldn't rename \"%s\": %s";
|
const char msg[] = "Couldn't rename \"%ls\": %s";
|
||||||
ShowMessage(msg, Shorten(ToWString(old_dir), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
ShowMessage(msg, wideShorten(ToWString(old_dir), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1518,14 +1518,14 @@ void EditDirectoryName::Run()
|
|||||||
std::string full_new_dir = Config.mpd_music_dir + myTagEditor->CurrentDir() + "/" + locale_to_utf_cpy(new_dir);
|
std::string full_new_dir = Config.mpd_music_dir + myTagEditor->CurrentDir() + "/" + locale_to_utf_cpy(new_dir);
|
||||||
if (rename(full_old_dir.c_str(), full_new_dir.c_str()) == 0)
|
if (rename(full_old_dir.c_str(), full_new_dir.c_str()) == 0)
|
||||||
{
|
{
|
||||||
const char msg[] = "Directory renamed to \"%s\"";
|
const char msg[] = "Directory renamed to \"%ls\"";
|
||||||
ShowMessage(msg, Shorten(ToWString(new_dir), COLS-const_strlen(msg)).c_str());
|
ShowMessage(msg, wideShorten(ToWString(new_dir), COLS-const_strlen(msg)).c_str());
|
||||||
Mpd.UpdateDirectory(myTagEditor->CurrentDir());
|
Mpd.UpdateDirectory(myTagEditor->CurrentDir());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char msg[] = "Couldn't rename \"%s\": %s";
|
const char msg[] = "Couldn't rename \"%ls\": %s";
|
||||||
ShowMessage(msg, Shorten(ToWString(old_dir), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
ShowMessage(msg, wideShorten(ToWString(old_dir), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1558,8 +1558,8 @@ void EditPlaylistName::Run()
|
|||||||
{
|
{
|
||||||
if (Mpd.Rename(locale_to_utf_cpy(old_name), locale_to_utf_cpy(new_name)))
|
if (Mpd.Rename(locale_to_utf_cpy(old_name), locale_to_utf_cpy(new_name)))
|
||||||
{
|
{
|
||||||
const char msg[] = "Playlist renamed to \"%s\"";
|
const char msg[] = "Playlist renamed to \"%ls\"";
|
||||||
ShowMessage(msg, Shorten(ToWString(new_name), COLS-const_strlen(msg)).c_str());
|
ShowMessage(msg, wideShorten(ToWString(new_name), COLS-const_strlen(msg)).c_str());
|
||||||
if (myBrowser->Main() && !myBrowser->isLocal())
|
if (myBrowser->Main() && !myBrowser->isLocal())
|
||||||
myBrowser->GetDirectory("/");
|
myBrowser->GetDirectory("/");
|
||||||
if (myPlaylistEditor->Main())
|
if (myPlaylistEditor->Main())
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "bindings.h"
|
#include "bindings.h"
|
||||||
#include "utility/string.h"
|
#include "utility/string.h"
|
||||||
|
#include "utility/wide_string.h"
|
||||||
|
|
||||||
BindingsConfiguration Bindings;
|
BindingsConfiguration Bindings;
|
||||||
|
|
||||||
|
|||||||
@@ -549,13 +549,13 @@ void Browser::ClearDirectory(const std::string &path) const
|
|||||||
ClearDirectory(full_path);
|
ClearDirectory(full_path);
|
||||||
if (remove(full_path.c_str()) == 0)
|
if (remove(full_path.c_str()) == 0)
|
||||||
{
|
{
|
||||||
const char msg[] = "Deleting \"%s\"...";
|
const char msg[] = "Deleting \"%ls\"...";
|
||||||
ShowMessage(msg, Shorten(ToWString(full_path), COLS-const_strlen(msg)).c_str());
|
ShowMessage(msg, wideShorten(ToWString(full_path), COLS-const_strlen(msg)).c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char msg[] = "Couldn't remove \"%s\": %s";
|
const char msg[] = "Couldn't remove \"%ls\": %s";
|
||||||
ShowMessage(msg, Shorten(ToWString(full_path), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
ShowMessage(msg, wideShorten(ToWString(full_path), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ void showSongsInColumns(NC::Menu<T> &menu, const MPD::Song &s, HasSongs &screen)
|
|||||||
}
|
}
|
||||||
if (tag.empty() && it->display_empty_tag)
|
if (tag.empty() && it->display_empty_tag)
|
||||||
tag = ToWString(Config.empty_tag);
|
tag = ToWString(Config.empty_tag);
|
||||||
NC::Window::cut(tag, width);
|
wideCut(tag, width);
|
||||||
|
|
||||||
if (!discard_colors && it->color != NC::clDefault)
|
if (!discard_colors && it->color != NC::clDefault)
|
||||||
menu << it->color;
|
menu << it->color;
|
||||||
@@ -234,7 +234,7 @@ void showSongsInColumns(NC::Menu<T> &menu, const MPD::Song &s, HasSongs &screen)
|
|||||||
// if column uses right alignment, calculate proper offset.
|
// if column uses right alignment, calculate proper offset.
|
||||||
// otherwise just assume offset is 0, ie. we start from the left.
|
// otherwise just assume offset is 0, ie. we start from the left.
|
||||||
if (it->right_alignment)
|
if (it->right_alignment)
|
||||||
x_off = std::max(0, width - int(NC::Window::length(tag)));
|
x_off = std::max(0, width - int(wideLength(tag)));
|
||||||
|
|
||||||
whline(menu.raw(), KEY_SPACE, width);
|
whline(menu.raw(), KEY_SPACE, width);
|
||||||
menu.goToXY(x + x_off, y);
|
menu.goToXY(x + x_off, y);
|
||||||
@@ -314,9 +314,9 @@ std::string Display::Columns(size_t list_width)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
name = it->name;
|
name = it->name;
|
||||||
NC::Window::cut(name, width);
|
wideCut(name, width);
|
||||||
|
|
||||||
int x_off = std::max(0, width - int(NC::Window::length(name)));
|
int x_off = std::max(0, width - int(wideLength(name)));
|
||||||
if (it->right_alignment)
|
if (it->right_alignment)
|
||||||
{
|
{
|
||||||
result += std::string(x_off, KEY_SPACE);
|
result += std::string(x_off, KEY_SPACE);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "help.h"
|
#include "help.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
|
#include "utility/wide_string.h"
|
||||||
|
|
||||||
using Global::MainHeight;
|
using Global::MainHeight;
|
||||||
using Global::MainStartY;
|
using Global::MainStartY;
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ std::wstring Scroller(const std::wstring &str, size_t &pos, size_t width)
|
|||||||
if (!Config.header_text_scrolling)
|
if (!Config.header_text_scrolling)
|
||||||
return s;
|
return s;
|
||||||
std::wstring result;
|
std::wstring result;
|
||||||
size_t len = NC::Window::length(s);
|
size_t len = wideLength(s);
|
||||||
|
|
||||||
if (len > width)
|
if (len > width)
|
||||||
{
|
{
|
||||||
@@ -322,15 +322,3 @@ std::wstring Scroller(const std::wstring &str, size_t &pos, size_t width)
|
|||||||
result = s;
|
result = s;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Shorten(const std::wstring &s, size_t max_length)
|
|
||||||
{
|
|
||||||
if (s.length() <= max_length)
|
|
||||||
return ToString(s);
|
|
||||||
if (max_length < 2)
|
|
||||||
return "";
|
|
||||||
std::wstring result(s, 0, max_length/2-!(max_length%2));
|
|
||||||
result += L"..";
|
|
||||||
result += s.substr(s.length()-max_length/2+1);
|
|
||||||
return ToString(result);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
|
#include "utility/wide_string.h"
|
||||||
|
|
||||||
inline HasSongs *hasSongs(BasicScreen *screen)
|
inline HasSongs *hasSongs(BasicScreen *screen)
|
||||||
{
|
{
|
||||||
@@ -463,6 +464,4 @@ void markSongsInPlaylist(std::shared_ptr<ProxySongList> pl);
|
|||||||
|
|
||||||
std::wstring Scroller(const std::wstring &str, size_t &pos, size_t width);
|
std::wstring Scroller(const std::wstring &str, size_t &pos, size_t width);
|
||||||
|
|
||||||
std::string Shorten(const std::wstring &s, size_t max_length);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -210,8 +210,8 @@ void Lastfm::Refetch()
|
|||||||
{
|
{
|
||||||
if (remove(itsFilename.c_str()) && errno != ENOENT)
|
if (remove(itsFilename.c_str()) && errno != ENOENT)
|
||||||
{
|
{
|
||||||
const char msg[] = "Couldn't remove \"%s\": %s";
|
const char msg[] = "Couldn't remove \"%ls\": %s";
|
||||||
ShowMessage(msg, Shorten(ToWString(itsFilename), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
ShowMessage(msg, wideShorten(ToWString(itsFilename), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Load();
|
Load();
|
||||||
|
|||||||
@@ -405,8 +405,8 @@ void Lyrics::Refetch()
|
|||||||
{
|
{
|
||||||
if (remove(itsFilename.c_str()) && errno != ENOENT)
|
if (remove(itsFilename.c_str()) && errno != ENOENT)
|
||||||
{
|
{
|
||||||
const char msg[] = "Couldn't remove \"%s\": %s";
|
const char msg[] = "Couldn't remove \"%ls\": %s";
|
||||||
ShowMessage(msg, Shorten(ToWString(itsFilename), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
ShowMessage(msg, wideShorten(ToWString(itsFilename), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Load();
|
Load();
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include "scrollpad.h"
|
#include "scrollpad.h"
|
||||||
|
#include "utility/wide_string.h"
|
||||||
|
|
||||||
namespace NC {//
|
namespace NC {//
|
||||||
|
|
||||||
|
|||||||
@@ -545,7 +545,7 @@ void Configuration::Read()
|
|||||||
{
|
{
|
||||||
selected_item_prefix.clear();
|
selected_item_prefix.clear();
|
||||||
String2Buffer(v, selected_item_prefix);
|
String2Buffer(v, selected_item_prefix);
|
||||||
selected_item_prefix_length = NC::Window::length(ToWString(selected_item_prefix.str()));
|
selected_item_prefix_length = wideLength(ToWString(selected_item_prefix.str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (name == "selected_item_suffix")
|
else if (name == "selected_item_suffix")
|
||||||
@@ -554,7 +554,7 @@ void Configuration::Read()
|
|||||||
{
|
{
|
||||||
selected_item_suffix.clear();
|
selected_item_suffix.clear();
|
||||||
String2Buffer(v, selected_item_suffix);
|
String2Buffer(v, selected_item_suffix);
|
||||||
selected_item_suffix_length = NC::Window::length(ToWString(selected_item_suffix.str()));
|
selected_item_suffix_length = wideLength(ToWString(selected_item_suffix.str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (name == "now_playing_prefix")
|
else if (name == "now_playing_prefix")
|
||||||
@@ -563,7 +563,7 @@ void Configuration::Read()
|
|||||||
{
|
{
|
||||||
now_playing_prefix.clear();
|
now_playing_prefix.clear();
|
||||||
String2Buffer(v, now_playing_prefix);
|
String2Buffer(v, now_playing_prefix);
|
||||||
now_playing_prefix_length = NC::Window::length(ToWString(now_playing_prefix.str()));
|
now_playing_prefix_length = wideLength(ToWString(now_playing_prefix.str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (name == "now_playing_suffix")
|
else if (name == "now_playing_suffix")
|
||||||
@@ -572,7 +572,7 @@ void Configuration::Read()
|
|||||||
{
|
{
|
||||||
now_playing_suffix.clear();
|
now_playing_suffix.clear();
|
||||||
String2Buffer(ToWString(v), now_playing_suffix);
|
String2Buffer(ToWString(v), now_playing_suffix);
|
||||||
now_playing_suffix_length = NC::Window::length(now_playing_suffix.str());
|
now_playing_suffix_length = wideLength(now_playing_suffix.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (name == "color1")
|
else if (name == "color1")
|
||||||
|
|||||||
31
src/song.cpp
31
src/song.cpp
@@ -26,6 +26,7 @@
|
|||||||
#include "song.h"
|
#include "song.h"
|
||||||
#include "utility/numeric_conversions.h"
|
#include "utility/numeric_conversions.h"
|
||||||
#include "utility/type_conversions.h"
|
#include "utility/type_conversions.h"
|
||||||
|
#include "utility/wide_string.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
namespace {//
|
namespace {//
|
||||||
@@ -38,19 +39,6 @@ size_t calc_hash(const char* s, unsigned seed = 0)
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
// temporary hack, it won't work properly with wide characters
|
|
||||||
std::string Shorten(const std::wstring &s, size_t max_length)
|
|
||||||
{
|
|
||||||
if (s.length() <= max_length)
|
|
||||||
return ToString(s);
|
|
||||||
if (max_length < 2)
|
|
||||||
return "";
|
|
||||||
std::wstring result(s, 0, max_length/2-!(max_length%2));
|
|
||||||
result += L"..";
|
|
||||||
result += s.substr(s.length()-max_length/2+1);
|
|
||||||
return ToString(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MPD {//
|
namespace MPD {//
|
||||||
@@ -289,10 +277,12 @@ std::string Song::ShowTime(unsigned length)
|
|||||||
length -= minutes*60;
|
length -= minutes*60;
|
||||||
int seconds = length;
|
int seconds = length;
|
||||||
|
|
||||||
|
std::string result;
|
||||||
if (hours > 0)
|
if (hours > 0)
|
||||||
return print<32, std::string>::apply("%d:%02d:%02d", hours, minutes, seconds);
|
result = print<32, std::string>::apply("%d:%02d:%02d", hours, minutes, seconds);
|
||||||
else
|
else
|
||||||
return print<32, std::string>::apply("%d:%02d", minutes, seconds);
|
result = print<32, std::string>::apply("%d:%02d", minutes, seconds);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MPD::Song::isFormatOk(const std::string &type, const std::string &fmt)
|
bool MPD::Song::isFormatOk(const std::string &type, const std::string &fmt)
|
||||||
@@ -324,7 +314,8 @@ bool MPD::Song::isFormatOk(const std::string &type, const std::string &fmt)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Song::ParseFormat(std::string::const_iterator &it, const std::string &tag_separator, const std::string &escape_chars) const
|
std::string Song::ParseFormat(std::string::const_iterator &it, const std::string &tag_separator,
|
||||||
|
const std::string &escape_chars) const
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
bool has_some_tags = 0;
|
bool has_some_tags = 0;
|
||||||
@@ -371,12 +362,8 @@ std::string Song::ParseFormat(std::string::const_iterator &it, const std::string
|
|||||||
}
|
}
|
||||||
if (!tag.empty() && (get != &MPD::Song::getLength || getDuration() > 0))
|
if (!tag.empty() && (get != &MPD::Song::getLength || getDuration() > 0))
|
||||||
{
|
{
|
||||||
if (delimiter)
|
if (delimiter && tag.size() > delimiter)
|
||||||
{
|
tag = ToString(wideShorten(ToWString(tag), delimiter));
|
||||||
std::wstring s = ToWString(tag);
|
|
||||||
if (NC::Window::length(s) > delimiter)
|
|
||||||
tag = Shorten(s, delimiter);
|
|
||||||
}
|
|
||||||
has_some_tags = 1;
|
has_some_tags = 1;
|
||||||
result += tag;
|
result += tag;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -447,11 +447,11 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *)
|
|||||||
String2Buffer(ToWString(utf_to_locale_cpy(np.toString(Config.new_header_first_line, "$"))), first);
|
String2Buffer(ToWString(utf_to_locale_cpy(np.toString(Config.new_header_first_line, "$"))), first);
|
||||||
String2Buffer(ToWString(utf_to_locale_cpy(np.toString(Config.new_header_second_line, "$"))), second);
|
String2Buffer(ToWString(utf_to_locale_cpy(np.toString(Config.new_header_second_line, "$"))), second);
|
||||||
|
|
||||||
size_t first_len = NC::Window::length(first.str());
|
size_t first_len = wideLength(first.str());
|
||||||
size_t first_margin = (std::max(tracklength.length()+1, VolumeState.length()))*2;
|
size_t first_margin = (std::max(tracklength.length()+1, VolumeState.length()))*2;
|
||||||
size_t first_start = first_len < COLS-first_margin ? (COLS-first_len)/2 : tracklength.length()+1;
|
size_t first_start = first_len < COLS-first_margin ? (COLS-first_len)/2 : tracklength.length()+1;
|
||||||
|
|
||||||
size_t second_len = NC::Window::length(second.str());
|
size_t second_len = wideLength(second.str());
|
||||||
size_t second_margin = (std::max(player_state.length(), size_t(8))+1)*2;
|
size_t second_margin = (std::max(player_state.length(), size_t(8))+1)*2;
|
||||||
size_t second_start = second_len < COLS-second_margin ? (COLS-second_len)/2 : player_state.length()+1;
|
size_t second_start = second_len < COLS-second_margin ? (COLS-second_len)/2 : player_state.length()+1;
|
||||||
|
|
||||||
@@ -654,7 +654,7 @@ void DrawHeader()
|
|||||||
*wHeader << NC::fmtBold << Config.alternative_ui_separator_color;
|
*wHeader << NC::fmtBold << Config.alternative_ui_separator_color;
|
||||||
mvwhline(wHeader->raw(), 2, 0, 0, COLS);
|
mvwhline(wHeader->raw(), 2, 0, 0, COLS);
|
||||||
mvwhline(wHeader->raw(), 4, 0, 0, COLS);
|
mvwhline(wHeader->raw(), 4, 0, 0, COLS);
|
||||||
*wHeader << NC::XY((COLS-NC::Window::length(title))/2, 3);
|
*wHeader << NC::XY((COLS-wideLength(title))/2, 3);
|
||||||
*wHeader << Config.header_color << title << NC::clEnd;
|
*wHeader << Config.header_color << title << NC::clEnd;
|
||||||
*wHeader << NC::clEnd << NC::fmtBoldEnd;
|
*wHeader << NC::clEnd << NC::fmtBoldEnd;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "utility/numeric_conversions.h"
|
#include "utility/numeric_conversions.h"
|
||||||
|
#include "utility/wide_string.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
namespace NC {//
|
namespace NC {//
|
||||||
@@ -306,7 +307,7 @@ template <typename CharT> void basic_buffer<CharT>::write(
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
std::basic_string<CharT> s = m_string;
|
std::basic_string<CharT> s = m_string;
|
||||||
size_t len = Window::length(s);
|
size_t len = wideLength(s);
|
||||||
|
|
||||||
if (len > width)
|
if (len > width)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -596,8 +596,8 @@ void TagEditor::EnterPressed()
|
|||||||
ShowMessage("Writing tags in \"%s\"...", (*it)->getName().c_str());
|
ShowMessage("Writing tags in \"%s\"...", (*it)->getName().c_str());
|
||||||
if (!WriteTags(**it))
|
if (!WriteTags(**it))
|
||||||
{
|
{
|
||||||
const char msg[] = "Error while writing tags in \"%s\"";
|
const char msg[] = "Error while writing tags in \"%ls\"";
|
||||||
ShowMessage(msg, Shorten(ToWString((*it)->getURI()), COLS-const_strlen(msg)).c_str());
|
ShowMessage(msg, wideShorten(ToWString((*it)->getURI()), COLS-const_strlen(msg)).c_str());
|
||||||
success = 0;
|
success = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,10 +91,8 @@ void TinyTagEditor::SwitchTo()
|
|||||||
full_path += Config.mpd_music_dir;
|
full_path += Config.mpd_music_dir;
|
||||||
full_path += itsEdited.getURI();
|
full_path += itsEdited.getURI();
|
||||||
|
|
||||||
std::string message = "Couldn't read file \"";
|
const char msg[] = "Couldn't read file \"%ls\"";
|
||||||
message += Shorten(ToWString(full_path), COLS-message.length()-3);
|
ShowMessage(msg, wideShorten(ToWString(full_path), COLS-const_strlen(msg)).c_str());
|
||||||
message += "\"!";
|
|
||||||
ShowMessage("%s", message.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,31 +44,6 @@ bool isInteger(const char *s, bool accept_signed)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString(const std::wstring &ws)
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
char s[MB_CUR_MAX];
|
|
||||||
for (size_t i = 0; i < ws.length(); ++i)
|
|
||||||
{
|
|
||||||
int n = wcrtomb(s, ws[i], 0);
|
|
||||||
if (n > 0)
|
|
||||||
result.append(s, n);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring ToWString(const std::string &s)
|
|
||||||
{
|
|
||||||
std::wstring result;
|
|
||||||
wchar_t *ws = new wchar_t[s.length()];
|
|
||||||
const char *c_s = s.c_str();
|
|
||||||
int n = mbsrtowcs(ws, &c_s, s.length(), 0);
|
|
||||||
if (n > 0)
|
|
||||||
result.append(ws, n);
|
|
||||||
delete [] ws;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> split(const std::string &s, const std::string &delimiter)
|
std::vector<std::string> split(const std::string &s, const std::string &delimiter)
|
||||||
{
|
{
|
||||||
if (delimiter.empty())
|
if (delimiter.empty())
|
||||||
|
|||||||
@@ -67,9 +67,6 @@ int stringToInt(const std::string &s);
|
|||||||
long stringToLongInt(const std::string &s);
|
long stringToLongInt(const std::string &s);
|
||||||
bool isInteger(const char *s, bool accept_signed);
|
bool isInteger(const char *s, bool accept_signed);
|
||||||
|
|
||||||
std::string ToString(const std::wstring &ws);
|
|
||||||
std::wstring ToWString(const std::string &s);
|
|
||||||
|
|
||||||
std::vector<std::string> split(const std::string &s, const std::string &delimiter);
|
std::vector<std::string> split(const std::string &s, const std::string &delimiter);
|
||||||
void replace(std::string &s, const std::string &from, const std::string &to);
|
void replace(std::string &s, const std::string &from, const std::string &to);
|
||||||
|
|
||||||
|
|||||||
105
src/utility/wide_string.cpp
Normal file
105
src/utility/wide_string.cpp
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2008-2012 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 "utility/wide_string.h"
|
||||||
|
|
||||||
|
std::string ToString(const std::wstring &ws)
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
char s[MB_CUR_MAX];
|
||||||
|
for (size_t i = 0; i < ws.length(); ++i)
|
||||||
|
{
|
||||||
|
int n = wcrtomb(s, ws[i], 0);
|
||||||
|
if (n > 0)
|
||||||
|
result.append(s, n);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring ToWString(const std::string &s)
|
||||||
|
{
|
||||||
|
std::wstring result;
|
||||||
|
wchar_t *ws = new wchar_t[s.length()];
|
||||||
|
const char *c_s = s.c_str();
|
||||||
|
int n = mbsrtowcs(ws, &c_s, s.length(), 0);
|
||||||
|
if (n > 0)
|
||||||
|
result.append(ws, n);
|
||||||
|
delete [] ws;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t wideLength(const std::wstring &ws)
|
||||||
|
{
|
||||||
|
int len = wcswidth(ws.c_str(), -1);
|
||||||
|
if (len < 0)
|
||||||
|
return ws.length();
|
||||||
|
else
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wideCut(std::wstring &ws, size_t max_length)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
int remained_len = max_length;
|
||||||
|
for (; i < ws.length(); ++i)
|
||||||
|
{
|
||||||
|
remained_len -= wcwidth(ws[i]);
|
||||||
|
if (remained_len < 0)
|
||||||
|
{
|
||||||
|
ws.resize(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring wideShorten(const std::wstring &ws, size_t max_length)
|
||||||
|
{
|
||||||
|
std::wstring result;
|
||||||
|
if (wideLength(ws) > max_length)
|
||||||
|
{
|
||||||
|
const size_t half_max = max_length/2 - 1;
|
||||||
|
size_t len = 0;
|
||||||
|
// get beginning of string
|
||||||
|
for (auto it = ws.begin(); it != ws.end(); ++it)
|
||||||
|
{
|
||||||
|
len += wcwidth(*it);
|
||||||
|
if (len > half_max)
|
||||||
|
break;
|
||||||
|
result += *it;
|
||||||
|
}
|
||||||
|
len = 0;
|
||||||
|
std::wstring end;
|
||||||
|
// get end of string in reverse order
|
||||||
|
for (auto it = ws.rbegin(); it != ws.rend(); ++it)
|
||||||
|
{
|
||||||
|
len += wcwidth(*it);
|
||||||
|
if (len > half_max)
|
||||||
|
break;
|
||||||
|
end += *it;
|
||||||
|
}
|
||||||
|
// apply end of string to its beginning
|
||||||
|
result += L"..";
|
||||||
|
result.append(end.rbegin(), end.rend());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = ws;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
34
src/utility/wide_string.h
Normal file
34
src/utility/wide_string.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2008-2012 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _UTILITY_WIDE_STRING
|
||||||
|
#define _UTILITY_WIDE_STRING
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
std::string ToString(const std::wstring &ws);
|
||||||
|
std::wstring ToWString(const std::string &s);
|
||||||
|
|
||||||
|
size_t wideLength(const std::wstring &ws);
|
||||||
|
|
||||||
|
void wideCut(std::wstring &ws, size_t max_length);
|
||||||
|
std::wstring wideShorten(const std::wstring &ws, size_t max_length);
|
||||||
|
|
||||||
|
#endif // _UTILITY_WIDE_STRING
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "utility/string.h"
|
#include "utility/string.h"
|
||||||
|
#include "utility/wide_string.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
namespace NC {//
|
namespace NC {//
|
||||||
@@ -456,7 +457,7 @@ std::string Window::getString(const std::string &base, size_t length_, size_t wi
|
|||||||
block_scrolling = 0;
|
block_scrolling = 0;
|
||||||
|
|
||||||
maxbeginning = block_scrolling ? 0 : (tmp->length() < width ? 0 : tmp->length()-width);
|
maxbeginning = block_scrolling ? 0 : (tmp->length() < width ? 0 : tmp->length()-width);
|
||||||
maxx = minx + (Window::length(*tmp) < width ? Window::length(*tmp) : width);
|
maxx = minx + (wideLength(*tmp) < width ? wideLength(*tmp) : width);
|
||||||
|
|
||||||
real_maxx = minx + (tmp->length() < width ? tmp->length() : width);
|
real_maxx = minx + (tmp->length() < width ? tmp->length() : width);
|
||||||
|
|
||||||
@@ -902,29 +903,4 @@ Window &Window::operator<<(size_t s)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Window::length(const std::wstring &ws)
|
|
||||||
{
|
|
||||||
# ifdef WIN32
|
|
||||||
return ws.length();
|
|
||||||
# else
|
|
||||||
int len = wcswidth(ws.c_str(), -1);
|
|
||||||
return len < 0 ? ws.length() : len;
|
|
||||||
# endif // WIN32
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::cut(std::wstring &ws, size_t max_len)
|
|
||||||
{
|
|
||||||
size_t i = 0;
|
|
||||||
int remained_len = max_len;
|
|
||||||
for (; i < ws.length(); ++i)
|
|
||||||
{
|
|
||||||
remained_len -= wcwidth(ws[i]);
|
|
||||||
if (remained_len < 0)
|
|
||||||
{
|
|
||||||
ws.resize(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/window.h
12
src/window.h
@@ -413,18 +413,6 @@ struct Window
|
|||||||
/// @param ws wide string to be printed
|
/// @param ws wide string to be printed
|
||||||
/// @return reference to itself
|
/// @return reference to itself
|
||||||
Window &operator<<(const std::wstring &ws);
|
Window &operator<<(const std::wstring &ws);
|
||||||
|
|
||||||
/// Measures real length of wide string (required if e.g. asian characters are used)
|
|
||||||
/// @param ws wide string that real length has to be measured
|
|
||||||
/// @return real length of wide string
|
|
||||||
static size_t length(const std::wstring &ws);
|
|
||||||
|
|
||||||
/// Cuts string so it fits desired length on the screen. Note that it uses
|
|
||||||
/// wcwidth to check real width of all characters it contains. If string
|
|
||||||
/// fits requested length it's not modified at all.
|
|
||||||
/// @param ws wide string to be cut
|
|
||||||
/// @param max_len maximal length of string
|
|
||||||
static void cut(std::wstring &ws, size_t max_len);
|
|
||||||
protected:
|
protected:
|
||||||
/// Sets colors of window (interal use only)
|
/// Sets colors of window (interal use only)
|
||||||
/// @param fg foregound color
|
/// @param fg foregound color
|
||||||
|
|||||||
Reference in New Issue
Block a user