settings: support customizable tags separator

This commit is contained in:
Andrzej Rybczak
2012-09-12 21:44:27 +02:00
parent 6da434b5b2
commit d55070754d
21 changed files with 62 additions and 48 deletions

View File

@@ -1362,7 +1362,7 @@ void EditLibraryTag::Run()
for (auto s = songs.begin(); s != songs.end(); ++s)
{
MPD::MutableSong es = *s;
es.setTags(set, new_tag);
es.setTags(set, new_tag, Config.tags_separator);
Statusbar::msg("Updating tags in \"%s\"...", es.getName().c_str());
std::string path = Config.mpd_music_dir + es.getURI();
if (!TagEditor::WriteTags(es))

View File

@@ -616,9 +616,9 @@ std::string ItemToString(const MPD::Item &item)
break;
case MPD::itSong:
if (Config.columns_in_browser)
result = item.song->toString(Config.song_in_columns_to_string_format);
result = item.song->toString(Config.song_in_columns_to_string_format, Config.tags_separator);
else
result = item.song->toString(Config.song_list_format_dollar_free);
result = item.song->toString(Config.song_list_format_dollar_free, Config.tags_separator);
break;
case MPD::itPlaylist:
result = Config.browser_playlist_prefix.str() + getBasename(item.name);

View File

@@ -189,7 +189,7 @@ void ParseArgv(int argc, char **argv)
}
}
std::cout << IConv::utf8ToLocale(
Mpd.GetCurrentlyPlayingSong().toString(now_playing_format)) << "\n";
Mpd.GetCurrentlyPlayingSong().toString(now_playing_format, Config.tags_separator)) << "\n";
}
exit(0);
}

View File

@@ -109,7 +109,7 @@ void showSongs(NC::Menu<T> &menu, const MPD::Song &s, HasSongs &screen, const st
setProperties(menu, s, screen, separate_albums, is_now_playing, is_selected, discard_colors);
size_t y = menu.getY();
std::string line = s.toString(format, "$");
std::string line = s.toString(format, Config.tags_separator, "$");
for (auto it = line.begin(); it != line.end(); ++it)
{
if (*it == '$')
@@ -223,7 +223,7 @@ void showSongsInColumns(NC::Menu<T> &menu, const MPD::Song &s, HasSongs &screen)
for (size_t i = 0; i < it->type.length(); ++i)
{
MPD::Song::GetFunction get = charToGetFunction(it->type[i]);
tag = ToWString(get ? s.getTags(get) : "");
tag = ToWString(get ? s.getTags(get, Config.tags_separator) : "");
if (!tag.empty())
break;
}
@@ -365,7 +365,7 @@ void Display::Tags(NC::Menu<MPD::MutableSong> &menu)
size_t i = myTagEditor->TagTypes->choice();
if (i < 11)
{
ShowTag(menu, s.getTags(SongInfo::Tags[i].Get));
ShowTag(menu, s.getTags(SongInfo::Tags[i].Get, Config.tags_separator));
}
else if (i == 12)
{

View File

@@ -152,7 +152,7 @@ void Lyrics::SwitchTo()
std::wstring Lyrics::Title()
{
std::wstring result = L"Lyrics: ";
result += Scroller(ToWString(itsSong.toString("{%a - %t}")), itsScrollBegin, COLS-result.length()-(Config.new_design ? 2 : Global::VolumeState.length()));
result += Scroller(ToWString(itsSong.toString("{%a - %t}", ", ")), itsScrollBegin, COLS-result.length()-(Config.new_design ? 2 : Global::VolumeState.length()));
return result;
}
@@ -175,7 +175,7 @@ void Lyrics::DownloadInBackground(const MPD::Song &s)
f.close();
return;
}
Statusbar::msg("Fetching lyrics for \"%s\"...", s.toString(Config.song_status_format_no_colors).c_str());
Statusbar::msg("Fetching lyrics for \"%s\"...", s.toString(Config.song_status_format_no_colors, Config.tags_separator).c_str());
MPD::Song *s_copy = new MPD::Song(s);
pthread_mutex_lock(&itsDIBLock);

View File

@@ -85,7 +85,8 @@ public:
}}), m_cmp(std::locale(), Config.ignore_leading_the) { }
bool operator()(const MPD::Song &a, const MPD::Song &b) {
for (auto get = m_gets.begin(); get != m_gets.end(); ++get) {
int ret = m_cmp(a.getTags(*get), b.getTags(*get));
int ret = m_cmp(a.getTags(*get, Config.tags_separator),
b.getTags(*get, Config.tags_separator));
if (ret != 0)
return ret < 0;
}
@@ -902,7 +903,7 @@ std::string AlbumToString(const SearchConstraints &sc)
std::string SongToString(const MPD::Song &s)
{
return s.toString(Config.song_library_format);
return s.toString(Config.song_library_format, Config.tags_separator);
}
bool TagEntryMatcher(const Regex &rx, const std::string &tag)

View File

@@ -63,7 +63,7 @@ struct MutableSong : public Song
virtual unsigned getDuration() const;
void setDuration(unsigned duration);
void setTags(SetFunction set, const std::string &value, const std::string &delimiter = "");
void setTags(SetFunction set, const std::string &value, const std::string &delimiter);
bool isModified() const;
void clearModifications();

View File

@@ -203,7 +203,7 @@ void Playlist::EnterPressed()
std::function<void(MPD::SongList::iterator, MPD::SongList::iterator)> iter_swap, quick_sort;
auto song_cmp = [&cmp](const MPD::Song &a, const MPD::Song &b) -> bool {
for (size_t i = 0; i < SortOptions; ++i)
if (int ret = cmp(a.getTags((*SortDialog)[i].value().second), b.getTags((*SortDialog)[i].value().second)))
if (int ret = cmp(a.getTags((*SortDialog)[i].value().second, Config.tags_separator), b.getTags((*SortDialog)[i].value().second, Config.tags_separator)))
return ret < 0;
return a.getPosition() < b.getPosition();
};
@@ -518,7 +518,7 @@ bool Playlist::Add(const MPD::Song &s, bool play, int position)
int id = Mpd.AddSong(s, position);
if (id >= 0)
{
Statusbar::msg("Added to playlist: %s", s.toString(Config.song_status_format_no_colors).c_str());
Statusbar::msg("Added to playlist: %s", s.toString(Config.song_status_format_no_colors, Config.tags_separator).c_str());
if (play)
Mpd.PlayID(id);
return true;
@@ -621,9 +621,9 @@ std::string songToString(const MPD::Song &s)
{
std::string result;
if (Config.columns_in_playlist)
result = s.toString(Config.song_in_columns_to_string_format);
result = s.toString(Config.song_in_columns_to_string_format, Config.tags_separator);
else
result = s.toString(Config.song_list_format_dollar_free);
result = s.toString(Config.song_list_format_dollar_free, Config.tags_separator);
return result;
}

View File

@@ -521,9 +521,9 @@ std::string SongToString(const MPD::Song &s)
{
std::string result;
if (Config.columns_in_playlist_editor)
result = s.toString(Config.song_in_columns_to_string_format);
result = s.toString(Config.song_in_columns_to_string_format, Config.tags_separator);
else
result = s.toString(Config.song_list_format_dollar_free);
result = s.toString(Config.song_list_format_dollar_free, Config.tags_separator);
return result;
}

View File

@@ -588,9 +588,9 @@ std::string SEItemToString(const SEItem &ei)
if (ei.isSong())
{
if (Config.columns_in_search_engine)
result = ei.song().toString(Config.song_in_columns_to_string_format);
result = ei.song().toString(Config.song_in_columns_to_string_format, Config.tags_separator);
else
result = ei.song().toString(Config.song_list_format_dollar_free);
result = ei.song().toString(Config.song_list_format_dollar_free, Config.tags_separator);
}
else
result = ei.buffer().str();

View File

@@ -161,6 +161,7 @@ void Configuration::SetDefaults()
{
mpd_host = "localhost";
empty_tag = "<empty>";
tags_separator = " | ";
song_list_columns_format = "(7f)[green]{l} (25)[cyan]{a} (40)[]{t|f} (30)[red]{b}";
song_list_format = "{{%a - }{%t}|{$8%f$9}$R{$3(%l)$9}}";
song_list_format_dollar_free = RemoveDollarFormatting(song_list_format);
@@ -882,6 +883,11 @@ void Configuration::Read()
{
empty_tag = v; // is this case empty string is allowed
}
else if (name == "tags_separator")
{
if (!v.empty())
tags_separator = v;
}
else if (name == "empty_tag_color")
{
if (!v.empty())

View File

@@ -64,6 +64,7 @@ struct Configuration
std::string visualizer_fifo_path;
std::string visualizer_output_name;
std::string empty_tag;
std::string tags_separator;
std::string song_list_columns_format;
std::string song_list_format;
std::string song_list_format_dollar_free;

View File

@@ -193,7 +193,7 @@ std::string Song::getPriority(unsigned idx) const
return unsignedIntTo<std::string>::apply(getPrio());
}
std::string MPD::Song::getTags(GetFunction f, const std::string &tag_separator) const
std::string MPD::Song::getTags(GetFunction f, const std::string &tags_separator) const
{
assert(m_song);
unsigned idx = 0;
@@ -201,7 +201,7 @@ std::string MPD::Song::getTags(GetFunction f, const std::string &tag_separator)
for (std::string tag; !(tag = (this->*f)(idx)).empty(); ++idx)
{
if (!result.empty())
result += tag_separator;
result += tags_separator;
result += tag;
}
return result;
@@ -261,11 +261,11 @@ bool Song::empty() const
return m_song.get() == 0;
}
std::string Song::toString(const std::string &fmt, const std::string &tag_separator, const std::string &escape_chars) const
std::string Song::toString(const std::string &fmt, const std::string &tags_separator, const std::string &escape_chars) const
{
assert(m_song);
std::string::const_iterator it = fmt.begin();
return ParseFormat(it, tag_separator, escape_chars);
return ParseFormat(it, tags_separator, escape_chars);
}
std::string Song::ShowTime(unsigned length)
@@ -313,7 +313,7 @@ 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,
std::string Song::ParseFormat(std::string::const_iterator &it, const std::string &tags_separator,
const std::string &escape_chars) const
{
std::string result;
@@ -323,7 +323,7 @@ std::string Song::ParseFormat(std::string::const_iterator &it, const std::string
{
while (*it == '{')
{
std::string tags = ParseFormat(it, tag_separator, escape_chars);
std::string tags = ParseFormat(it, tags_separator, escape_chars);
if (!tags.empty())
{
has_some_tags = 1;
@@ -352,7 +352,7 @@ std::string Song::ParseFormat(std::string::const_iterator &it, const std::string
if (get)
{
std::string tag = getTags(get, tag_separator);
std::string tag = getTags(get, tags_separator);
if (!escape_chars.empty()) // prepend format escape character to all given chars to escape
{
for (size_t i = 0; i < escape_chars.length(); ++i)
@@ -384,7 +384,7 @@ std::string Song::ParseFormat(std::string::const_iterator &it, const std::string
--brace_counter;
}
if (*++it == '|')
return ParseFormat(++it, tag_separator, escape_chars);
return ParseFormat(++it, tags_separator, escape_chars);
else
return "";
}

View File

@@ -57,7 +57,7 @@ struct Song
virtual std::string getLength(unsigned idx = 0) const;
virtual std::string getPriority(unsigned idx = 0) const;
virtual std::string getTags(GetFunction f, const std::string &tag_separator = ", ") const;
virtual std::string getTags(GetFunction f, const std::string &tags_separator) const;
virtual unsigned getHash() const;
virtual unsigned getDuration() const;
@@ -71,7 +71,7 @@ struct Song
virtual bool empty() const;
virtual std::string toString(const std::string &fmt, const std::string &tag_separator = ", ",
virtual std::string toString(const std::string &fmt, const std::string &tags_separator,
const std::string &escape_chars = "") const;
static std::string ShowTime(unsigned length);
@@ -81,7 +81,7 @@ struct Song
private:
const char *getTag(mpd_tag_type type, unsigned idx) const;
std::string ParseFormat(std::string::const_iterator &it, const std::string &tag_separator,
std::string ParseFormat(std::string::const_iterator &it, const std::string &tags_separator,
const std::string &escape_chars) const;
std::shared_ptr<mpd_song> m_song;

View File

@@ -134,6 +134,6 @@ void SongInfo::PrepareSong(MPD::Song &s)
for (const Metadata *m = Tags; m->Name; ++m)
{
*w << NC::fmtBold << '\n' << ToWString(m->Name) << L": " << NC::fmtBoldEnd;
ShowTag(*w, s.getTags(m->Get));
ShowTag(*w, s.getTags(m->Get, Config.tags_separator));
}
}

View File

@@ -65,7 +65,7 @@ char mpd_db_updating;
void drawTitle(const MPD::Song &np)
{
assert(!np.empty());
windowTitle(np.toString(Config.song_window_title_format));
windowTitle(np.toString(Config.song_window_title_format, Config.tags_separator));
}
}
@@ -345,8 +345,8 @@ void Status::Changes::elapsedTime()
}
NC::WBuffer first, second;
stringToBuffer(ToWString(IConv::utf8ToLocale(np.toString(Config.new_header_first_line, "$"))), first);
stringToBuffer(ToWString(IConv::utf8ToLocale(np.toString(Config.new_header_second_line, "$"))), second);
stringToBuffer(ToWString(IConv::utf8ToLocale(np.toString(Config.new_header_first_line, Config.tags_separator, "$"))), first);
stringToBuffer(ToWString(IConv::utf8ToLocale(np.toString(Config.new_header_second_line, Config.tags_separator, "$"))), second);
size_t first_len = wideLength(first.str());
size_t first_margin = (std::max(tracklength.length()+1, VolumeState.length()))*2;
@@ -397,7 +397,7 @@ void Status::Changes::elapsedTime()
tracklength += "]";
}
NC::WBuffer np_song;
stringToBuffer(ToWString(IConv::utf8ToLocale(np.toString(Config.song_status_format, "$"))), np_song);
stringToBuffer(ToWString(IConv::utf8ToLocale(np.toString(Config.song_status_format, Config.tags_separator, "$"))), np_song);
*wFooter << NC::XY(0, 1) << wclrtoeol << NC::fmtBold << player_state << NC::fmtBoldEnd;
np_song.write(*wFooter, playing_song_scroll_begin, wFooter->getWidth()-player_state.length()-tracklength.length(), L" ** ");
*wFooter << NC::fmtBold << NC::XY(wFooter->getWidth()-tracklength.length(), 1) << tracklength << NC::fmtBoldEnd;

View File

@@ -526,19 +526,19 @@ void TagEditor::EnterPressed()
{
Statusbar::lock();
Statusbar::put() << NC::fmtBold << TagTypes->current().value() << NC::fmtBoldEnd << ": ";
std::string new_tag = wFooter->getString(Tags->current().value().getTags(get));
std::string new_tag = wFooter->getString(Tags->current().value().getTags(get, Config.tags_separator));
Statusbar::unlock();
for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it)
(*it)->setTags(set, new_tag);
(*it)->setTags(set, new_tag, Config.tags_separator);
}
else if (w == Tags)
{
Statusbar::lock();
Statusbar::put() << NC::fmtBold << TagTypes->current().value() << NC::fmtBoldEnd << ": ";
std::string new_tag = wFooter->getString(Tags->current().value().getTags(get));
std::string new_tag = wFooter->getString(Tags->current().value().getTags(get, Config.tags_separator));
Statusbar::unlock();
if (new_tag != Tags->current().value().getTags(get))
Tags->current().value().setTags(set, new_tag);
if (new_tag != Tags->current().value().getTags(get, Config.tags_separator))
Tags->current().value().setTags(set, new_tag, Config.tags_separator);
Tags->scroll(NC::wDown);
}
}
@@ -1254,7 +1254,7 @@ MPD::MutableSong::SetFunction IntoSetFunction(char c)
std::string GenerateFilename(const MPD::MutableSong &s, const std::string &pattern)
{
std::string result = s.toString(pattern);
std::string result = s.toString(pattern, Config.tags_separator);
removeInvalidCharsFromFilename(result);
return result;
}
@@ -1306,7 +1306,7 @@ std::string ParseFilename(MPD::MutableSong &s, std::string mask, bool preview)
{
MPD::MutableSong::SetFunction set = IntoSetFunction(it->first);
if (set)
s.setTags(set, it->second);
s.setTags(set, it->second, Config.tags_separator);
}
else
result << "%" << it->first << ": " << it->second << "\n";

View File

@@ -111,10 +111,11 @@ void TinyTagEditor::EnterPressed()
{
size_t pos = option-8;
Statusbar::put() << NC::fmtBold << SongInfo::Tags[pos].Name << ": " << NC::fmtBoldEnd;
itsEdited.setTags(SongInfo::Tags[pos].Set, Global::wFooter->getString(itsEdited.getTags(SongInfo::Tags[pos].Get)));
itsEdited.setTags(SongInfo::Tags[pos].Set, Global::wFooter->getString(
itsEdited.getTags(SongInfo::Tags[pos].Get, Config.tags_separator)), Config.tags_separator);
w->at(option).value().clear();
w->at(option).value() << NC::fmtBold << SongInfo::Tags[pos].Name << ':' << NC::fmtBoldEnd << ' ';
ShowTag(w->at(option).value(), itsEdited.getTags(SongInfo::Tags[pos].Get));
ShowTag(w->at(option).value(), itsEdited.getTags(SongInfo::Tags[pos].Get, Config.tags_separator));
}
else if (option == 20)
{
@@ -228,7 +229,7 @@ bool TinyTagEditor::getTags()
for (const SongInfo::Metadata *m = SongInfo::Tags; m->Name; ++m, ++pos)
{
w->at(pos).value() << NC::fmtBold << m->Name << ":" << NC::fmtBoldEnd << ' ';
ShowTag(w->at(pos).value(), itsEdited.getTags(m->Get));
ShowTag(w->at(pos).value(), itsEdited.getTags(m->Get, Config.tags_separator));
}
w->at(20).value() << NC::fmtBold << "Filename:" << NC::fmtBoldEnd << ' ' << itsEdited.getName();

View File

@@ -74,8 +74,8 @@ bool LocaleBasedItemSorting::operator()(const MPD::Item &a, const MPD::Item &b)
result = a.song->getMTime() > b.song->getMTime();
break;
case smCustomFormat:
result = m_cmp(a.song->toString(Config.browser_sort_format),
b.song->toString(Config.browser_sort_format));
result = m_cmp(a.song->toString(Config.browser_sort_format, Config.tags_separator),
b.song->toString(Config.browser_sort_format, Config.tags_separator));
break;
}
break;