move wstring related functions to wide_char file
This commit is contained in:
@@ -4,6 +4,7 @@ ncmpcpp_SOURCES = \
|
||||
utility/html.cpp \
|
||||
utility/string.cpp \
|
||||
utility/type_conversions.cpp \
|
||||
utility/wide_string.cpp \
|
||||
actions.cpp \
|
||||
bindings.cpp \
|
||||
browser.cpp \
|
||||
@@ -52,6 +53,7 @@ noinst_HEADERS = \
|
||||
utility/string.h \
|
||||
utility/numeric_conversions.h \
|
||||
utility/type_conversions.h \
|
||||
utility/wide_string.h \
|
||||
bindings.h \
|
||||
browser.h \
|
||||
charset.h \
|
||||
|
||||
@@ -800,7 +800,7 @@ void Delete::Run()
|
||||
question = "Delete ";
|
||||
question += itemTypeToString(item.type);
|
||||
question += " \"";
|
||||
question += Shorten(ToWString(name), COLS-question.size()-10);
|
||||
question += ToString(wideShorten(ToWString(name), COLS-question.size()-10));
|
||||
question += "\"?";
|
||||
}
|
||||
bool yes = AskYesNoQuestion(question, TraceMpdStatus);
|
||||
@@ -814,13 +814,13 @@ void Delete::Run()
|
||||
std::string name = i.type == MPD::itSong ? i.song->getName() : i.name;
|
||||
if (myBrowser->deleteItem(i))
|
||||
{
|
||||
const char msg[] = "\"%s\" deleted";
|
||||
ShowMessage(msg, Shorten(ToWString(name), COLS-const_strlen(msg)).c_str());
|
||||
const char msg[] = "\"%ls\" deleted";
|
||||
ShowMessage(msg, wideShorten(ToWString(name), COLS-const_strlen(msg)).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
const char msg[] = "Couldn't delete \"%s\": %s";
|
||||
ShowMessage(msg, Shorten(ToWString(name), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||
const char msg[] = "Couldn't delete \"%ls\": %s";
|
||||
ShowMessage(msg, wideShorten(ToWString(name), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
@@ -845,7 +845,7 @@ void Delete::Run()
|
||||
else
|
||||
{
|
||||
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 += "\"?";
|
||||
}
|
||||
bool yes = AskYesNoQuestion(question, TraceMpdStatus);
|
||||
@@ -1384,8 +1384,8 @@ void EditLibraryTag::Run()
|
||||
std::string path = Config.mpd_music_dir + es.getURI();
|
||||
if (!TagEditor::WriteTags(es))
|
||||
{
|
||||
const char msg[] = "Error while updating tags in \"%s\"";
|
||||
ShowMessage(msg, Shorten(ToWString(es.getURI()), COLS-const_strlen(msg)).c_str());
|
||||
const char msg[] = "Error while updating tags in \"%ls\"";
|
||||
ShowMessage(msg, wideShorten(ToWString(es.getURI()), COLS-const_strlen(msg)).c_str());
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
@@ -1430,16 +1430,16 @@ void EditLibraryAlbum::Run()
|
||||
TagLib::FileRef f(path.c_str());
|
||||
if (f.isNull())
|
||||
{
|
||||
const char msg[] = "Error while opening file \"%s\"";
|
||||
ShowMessage(msg, Shorten(ToWString((*myLibrary->Songs)[i].value().getURI()), COLS-const_strlen(msg)).c_str());
|
||||
const char msg[] = "Error while opening file \"%ls\"";
|
||||
ShowMessage(msg, wideShorten(ToWString((*myLibrary->Songs)[i].value().getURI()), COLS-const_strlen(msg)).c_str());
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
f.tag()->setAlbum(ToWString(new_album));
|
||||
if (!f.save())
|
||||
{
|
||||
const char msg[] = "Error while writing tags in \"%s\"";
|
||||
ShowMessage(msg, Shorten(ToWString((*myLibrary->Songs)[i].value().getURI()), COLS-const_strlen(msg)).c_str());
|
||||
const char msg[] = "Error while writing tags in \"%ls\"";
|
||||
ShowMessage(msg, wideShorten(ToWString((*myLibrary->Songs)[i].value().getURI()), COLS-const_strlen(msg)).c_str());
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
@@ -1491,16 +1491,16 @@ void EditDirectoryName::Run()
|
||||
int rename_result = rename(full_old_dir.c_str(), full_new_dir.c_str());
|
||||
if (rename_result == 0)
|
||||
{
|
||||
const char msg[] = "Directory renamed to \"%s\"";
|
||||
ShowMessage(msg, Shorten(ToWString(new_dir), COLS-const_strlen(msg)).c_str());
|
||||
const char msg[] = "Directory renamed to \"%ls\"";
|
||||
ShowMessage(msg, wideShorten(ToWString(new_dir), COLS-const_strlen(msg)).c_str());
|
||||
if (!myBrowser->isLocal())
|
||||
Mpd.UpdateDirectory(locale_to_utf_cpy(getSharedDirectory(old_dir, new_dir)));
|
||||
myBrowser->GetDirectory(myBrowser->CurrentDir());
|
||||
}
|
||||
else
|
||||
{
|
||||
const char msg[] = "Couldn't rename \"%s\": %s";
|
||||
ShowMessage(msg, Shorten(ToWString(old_dir), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||
const char msg[] = "Couldn't rename \"%ls\": %s";
|
||||
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);
|
||||
if (rename(full_old_dir.c_str(), full_new_dir.c_str()) == 0)
|
||||
{
|
||||
const char msg[] = "Directory renamed to \"%s\"";
|
||||
ShowMessage(msg, Shorten(ToWString(new_dir), COLS-const_strlen(msg)).c_str());
|
||||
const char msg[] = "Directory renamed to \"%ls\"";
|
||||
ShowMessage(msg, wideShorten(ToWString(new_dir), COLS-const_strlen(msg)).c_str());
|
||||
Mpd.UpdateDirectory(myTagEditor->CurrentDir());
|
||||
}
|
||||
else
|
||||
{
|
||||
const char msg[] = "Couldn't rename \"%s\": %s";
|
||||
ShowMessage(msg, Shorten(ToWString(old_dir), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||
const char msg[] = "Couldn't rename \"%ls\": %s";
|
||||
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)))
|
||||
{
|
||||
const char msg[] = "Playlist renamed to \"%s\"";
|
||||
ShowMessage(msg, Shorten(ToWString(new_name), COLS-const_strlen(msg)).c_str());
|
||||
const char msg[] = "Playlist renamed to \"%ls\"";
|
||||
ShowMessage(msg, wideShorten(ToWString(new_name), COLS-const_strlen(msg)).c_str());
|
||||
if (myBrowser->Main() && !myBrowser->isLocal())
|
||||
myBrowser->GetDirectory("/");
|
||||
if (myPlaylistEditor->Main())
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "global.h"
|
||||
#include "bindings.h"
|
||||
#include "utility/string.h"
|
||||
#include "utility/wide_string.h"
|
||||
|
||||
BindingsConfiguration Bindings;
|
||||
|
||||
|
||||
@@ -549,13 +549,13 @@ void Browser::ClearDirectory(const std::string &path) const
|
||||
ClearDirectory(full_path);
|
||||
if (remove(full_path.c_str()) == 0)
|
||||
{
|
||||
const char msg[] = "Deleting \"%s\"...";
|
||||
ShowMessage(msg, Shorten(ToWString(full_path), COLS-const_strlen(msg)).c_str());
|
||||
const char msg[] = "Deleting \"%ls\"...";
|
||||
ShowMessage(msg, wideShorten(ToWString(full_path), COLS-const_strlen(msg)).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
const char msg[] = "Couldn't remove \"%s\": %s";
|
||||
ShowMessage(msg, Shorten(ToWString(full_path), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||
const char msg[] = "Couldn't remove \"%ls\": %s";
|
||||
ShowMessage(msg, wideShorten(ToWString(full_path), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||
}
|
||||
}
|
||||
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)
|
||||
tag = ToWString(Config.empty_tag);
|
||||
NC::Window::cut(tag, width);
|
||||
wideCut(tag, width);
|
||||
|
||||
if (!discard_colors && it->color != NC::clDefault)
|
||||
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.
|
||||
// otherwise just assume offset is 0, ie. we start from the left.
|
||||
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);
|
||||
menu.goToXY(x + x_off, y);
|
||||
@@ -314,9 +314,9 @@ std::string Display::Columns(size_t list_width)
|
||||
}
|
||||
else
|
||||
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)
|
||||
{
|
||||
result += std::string(x_off, KEY_SPACE);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "help.h"
|
||||
#include "settings.h"
|
||||
#include "status.h"
|
||||
#include "utility/wide_string.h"
|
||||
|
||||
using Global::MainHeight;
|
||||
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)
|
||||
return s;
|
||||
std::wstring result;
|
||||
size_t len = NC::Window::length(s);
|
||||
size_t len = wideLength(s);
|
||||
|
||||
if (len > width)
|
||||
{
|
||||
@@ -322,15 +322,3 @@ std::wstring Scroller(const std::wstring &str, size_t &pos, size_t width)
|
||||
result = s;
|
||||
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 "settings.h"
|
||||
#include "status.h"
|
||||
#include "utility/wide_string.h"
|
||||
|
||||
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::string Shorten(const std::wstring &s, size_t max_length);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -210,8 +210,8 @@ void Lastfm::Refetch()
|
||||
{
|
||||
if (remove(itsFilename.c_str()) && errno != ENOENT)
|
||||
{
|
||||
const char msg[] = "Couldn't remove \"%s\": %s";
|
||||
ShowMessage(msg, Shorten(ToWString(itsFilename), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||
const char msg[] = "Couldn't remove \"%ls\": %s";
|
||||
ShowMessage(msg, wideShorten(ToWString(itsFilename), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||
return;
|
||||
}
|
||||
Load();
|
||||
|
||||
@@ -405,8 +405,8 @@ void Lyrics::Refetch()
|
||||
{
|
||||
if (remove(itsFilename.c_str()) && errno != ENOENT)
|
||||
{
|
||||
const char msg[] = "Couldn't remove \"%s\": %s";
|
||||
ShowMessage(msg, Shorten(ToWString(itsFilename), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||
const char msg[] = "Couldn't remove \"%ls\": %s";
|
||||
ShowMessage(msg, wideShorten(ToWString(itsFilename), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
|
||||
return;
|
||||
}
|
||||
Load();
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "scrollpad.h"
|
||||
#include "utility/wide_string.h"
|
||||
|
||||
namespace NC {//
|
||||
|
||||
|
||||
@@ -545,7 +545,7 @@ void Configuration::Read()
|
||||
{
|
||||
selected_item_prefix.clear();
|
||||
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")
|
||||
@@ -554,7 +554,7 @@ void Configuration::Read()
|
||||
{
|
||||
selected_item_suffix.clear();
|
||||
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")
|
||||
@@ -563,7 +563,7 @@ void Configuration::Read()
|
||||
{
|
||||
now_playing_prefix.clear();
|
||||
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")
|
||||
@@ -572,7 +572,7 @@ void Configuration::Read()
|
||||
{
|
||||
now_playing_suffix.clear();
|
||||
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")
|
||||
|
||||
31
src/song.cpp
31
src/song.cpp
@@ -26,6 +26,7 @@
|
||||
#include "song.h"
|
||||
#include "utility/numeric_conversions.h"
|
||||
#include "utility/type_conversions.h"
|
||||
#include "utility/wide_string.h"
|
||||
#include "window.h"
|
||||
|
||||
namespace {//
|
||||
@@ -38,19 +39,6 @@ size_t calc_hash(const char* s, unsigned seed = 0)
|
||||
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 {//
|
||||
@@ -289,10 +277,12 @@ std::string Song::ShowTime(unsigned length)
|
||||
length -= minutes*60;
|
||||
int seconds = length;
|
||||
|
||||
std::string result;
|
||||
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
|
||||
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)
|
||||
@@ -324,7 +314,8 @@ bool MPD::Song::isFormatOk(const std::string &type, const std::string &fmt)
|
||||
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;
|
||||
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 (delimiter)
|
||||
{
|
||||
std::wstring s = ToWString(tag);
|
||||
if (NC::Window::length(s) > delimiter)
|
||||
tag = Shorten(s, delimiter);
|
||||
}
|
||||
if (delimiter && tag.size() > delimiter)
|
||||
tag = ToString(wideShorten(ToWString(tag), delimiter));
|
||||
has_some_tags = 1;
|
||||
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_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_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_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;
|
||||
mvwhline(wHeader->raw(), 2, 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 << NC::clEnd << NC::fmtBoldEnd;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <list>
|
||||
#include "utility/numeric_conversions.h"
|
||||
#include "utility/wide_string.h"
|
||||
#include "window.h"
|
||||
|
||||
namespace NC {//
|
||||
@@ -306,7 +307,7 @@ template <typename CharT> void basic_buffer<CharT>::write(
|
||||
) const
|
||||
{
|
||||
std::basic_string<CharT> s = m_string;
|
||||
size_t len = Window::length(s);
|
||||
size_t len = wideLength(s);
|
||||
|
||||
if (len > width)
|
||||
{
|
||||
|
||||
@@ -596,8 +596,8 @@ void TagEditor::EnterPressed()
|
||||
ShowMessage("Writing tags in \"%s\"...", (*it)->getName().c_str());
|
||||
if (!WriteTags(**it))
|
||||
{
|
||||
const char msg[] = "Error while writing tags in \"%s\"";
|
||||
ShowMessage(msg, Shorten(ToWString((*it)->getURI()), COLS-const_strlen(msg)).c_str());
|
||||
const char msg[] = "Error while writing tags in \"%ls\"";
|
||||
ShowMessage(msg, wideShorten(ToWString((*it)->getURI()), COLS-const_strlen(msg)).c_str());
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -91,10 +91,8 @@ void TinyTagEditor::SwitchTo()
|
||||
full_path += Config.mpd_music_dir;
|
||||
full_path += itsEdited.getURI();
|
||||
|
||||
std::string message = "Couldn't read file \"";
|
||||
message += Shorten(ToWString(full_path), COLS-message.length()-3);
|
||||
message += "\"!";
|
||||
ShowMessage("%s", message.c_str());
|
||||
const char msg[] = "Couldn't read file \"%ls\"";
|
||||
ShowMessage(msg, wideShorten(ToWString(full_path), COLS-const_strlen(msg)).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,31 +44,6 @@ bool isInteger(const char *s, bool accept_signed)
|
||||
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)
|
||||
{
|
||||
if (delimiter.empty())
|
||||
|
||||
@@ -67,9 +67,6 @@ int stringToInt(const std::string &s);
|
||||
long stringToLongInt(const std::string &s);
|
||||
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);
|
||||
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 "utility/string.h"
|
||||
#include "utility/wide_string.h"
|
||||
#include "window.h"
|
||||
|
||||
namespace NC {//
|
||||
@@ -456,7 +457,7 @@ std::string Window::getString(const std::string &base, size_t length_, size_t wi
|
||||
block_scrolling = 0;
|
||||
|
||||
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);
|
||||
|
||||
@@ -902,29 +903,4 @@ Window &Window::operator<<(size_t s)
|
||||
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
|
||||
/// @return reference to itself
|
||||
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:
|
||||
/// Sets colors of window (interal use only)
|
||||
/// @param fg foregound color
|
||||
|
||||
Reference in New Issue
Block a user