From 4cb0e2232ae648775344b17cb3e48958d64a239a Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Wed, 29 Aug 2012 09:07:20 +0200 Subject: [PATCH] fix compilation --without-taglib --- src/Makefile.am | 4 + src/actions.cpp | 41 ++++---- src/browser.cpp | 5 +- src/conv.cpp | 24 ++--- src/conv.h | 3 +- src/display.cpp | 8 +- src/display.h | 2 +- src/helpers.cpp | 12 +-- src/helpers.h | 13 ++- src/mpdpp.cpp | 13 +++ src/mutable_song.cpp | 197 +++++++++++++++++++++++++++++++++++++++ src/mutable_song.h | 97 +++++++++++++++++++ src/song.cpp | 7 +- src/song.h | 60 ++++++------ src/song_info.cpp | 26 +++--- src/song_info.h | 2 +- src/string_utilities.cpp | 42 +++++++++ src/string_utilities.h | 29 ++++++ src/tag_editor.cpp | 193 ++++++++++++++++++-------------------- src/tag_editor.h | 28 +++--- src/tiny_tag_editor.cpp | 44 ++++----- src/tiny_tag_editor.h | 6 +- 22 files changed, 609 insertions(+), 247 deletions(-) create mode 100644 src/mutable_song.cpp create mode 100644 src/mutable_song.h create mode 100644 src/string_utilities.cpp create mode 100644 src/string_utilities.h diff --git a/src/Makefile.am b/src/Makefile.am index 36733300..a77134fc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,7 @@ ncmpcpp_SOURCES = \ media_library.cpp \ menu.cpp \ mpdpp.cpp \ + mutable_song.cpp \ ncmpcpp.cpp \ outputs.cpp \ playlist.cpp \ @@ -31,6 +32,7 @@ ncmpcpp_SOURCES = \ song.cpp \ song_info.cpp \ status.cpp \ + string_utilities.cpp \ tag_editor.cpp \ tiny_tag_editor.cpp \ tolower.cpp \ @@ -61,6 +63,7 @@ noinst_HEADERS = \ media_library.h \ menu.h \ mpdpp.h \ + mutable_song.h \ numeric_conversions.h \ outputs.h \ playlist_editor.h \ @@ -72,6 +75,7 @@ noinst_HEADERS = \ settings.h \ song.h \ song_info.h \ + string_utilities.h \ tag_editor.h \ tiny_tag_editor.h \ tolower.h \ diff --git a/src/actions.cpp b/src/actions.cpp index 8c7cbaba..dd3dba5c 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -1410,34 +1410,36 @@ void EditLibraryTag::Run() UnlockStatusbar(); if (!new_tag.empty() && new_tag != myLibrary->Artists->Current()) { - bool success = 1; - MPD::SongList list; ShowMessage("Updating tags..."); Mpd.StartSearch(1); Mpd.AddSearch(Config.media_lib_primary_tag, locale_to_utf_cpy(myLibrary->Artists->Current())); - Mpd.CommitSearch(list); - MPD::Song::SetFunction set = IntoSetFunction(Config.media_lib_primary_tag); + MPD::MutableSong::SetFunction set = IntoSetFunction(Config.media_lib_primary_tag); assert(set); - for (MPD::SongList::iterator it = list.begin(); it != list.end(); ++it) - { - (*it)->Localize(); - (*it)->SetTags(set, new_tag); - ShowMessage("Updating tags in \"%s\"...", (*it)->getName().c_str()); - std::string path = Config.mpd_music_dir + (*it)->getURI(); - if (!TagEditor::WriteTags(**it)) + bool success = true; + std::string dir_to_update; + Mpd.CommitSearchSongs([set, &new_tag, &success, &dir_to_update](MPD::Song &&s) { + if (!success) + return; + MPD::MutableSong es = s; + es.setTag(set, new_tag); + ShowMessage("Updating tags in \"%s\"...", es.getName().c_str()); + 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(TO_WSTRING((*it)->getURI()), COLS-static_strlen(msg)).c_str()); - success = 0; - break; + ShowMessage(msg, Shorten(TO_WSTRING(es.getURI()), COLS-static_strlen(msg)).c_str()); + success = false; } - } + if (dir_to_update.empty()) + dir_to_update = es.getDirectory(); + else + FindSharedDir(es.getDirectory(), dir_to_update); + }); if (success) { - Mpd.UpdateDirectory(locale_to_utf_cpy(FindSharedDir(list))); + Mpd.UpdateDirectory(dir_to_update); ShowMessage("Tags updated successfully"); } - FreeSongList(list); } # endif // HAVE_TAGLIB_H } @@ -1469,10 +1471,9 @@ void EditLibraryAlbum::Run() ShowMessage("Updating tags..."); for (size_t i = 0; i < myLibrary->Songs->Size(); ++i) { - (*myLibrary->Songs)[i].Localize(); ShowMessage("Updating tags in \"%s\"...", (*myLibrary->Songs)[i].getName().c_str()); std::string path = Config.mpd_music_dir + (*myLibrary->Songs)[i].getURI(); - TagLib::FileRef f(locale_to_utf_cpy(path).c_str()); + TagLib::FileRef f(path.c_str()); if (f.isNull()) { const char msg[] = "Error while opening file \"%s\""; @@ -1491,7 +1492,7 @@ void EditLibraryAlbum::Run() } if (success) { - Mpd.UpdateDirectory(locale_to_utf_cpy(FindSharedDir(myLibrary->Songs))); + Mpd.UpdateDirectory(FindSharedDir(myLibrary->Songs)); ShowMessage("Tags updated successfully"); } } diff --git a/src/browser.cpp b/src/browser.cpp index f23a3b43..ce48ebe7 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -478,8 +478,9 @@ void Browser::GetLocalDirectory(MPD::ItemList &v, const std::string &directory, mpd_pair file_pair = { "file", full_path.c_str() }; new_item.song = MPD::Song(mpd_song_begin(&file_pair)); # ifdef HAVE_TAGLIB_H - if (!recursively) - TagEditor::ReadTags(*new_item.song); + // FIXME + //if (!recursively) + // TagEditor::ReadTags(*new_item.song); # endif // HAVE_TAGLIB_H v.push_back(new_item); } diff --git a/src/conv.cpp b/src/conv.cpp index 4a46ccaf..cdff8fc1 100644 --- a/src/conv.cpp +++ b/src/conv.cpp @@ -233,32 +233,32 @@ MPD::Song::GetFunction toGetFunction(char c) } #ifdef HAVE_TAGLIB_H -MPD::Song::SetFunction IntoSetFunction(mpd_tag_type tag) +MPD::MutableSong::SetFunction IntoSetFunction(mpd_tag_type tag) { switch (tag) { case MPD_TAG_ARTIST: - return &MPD::Song::SetArtist; + return &MPD::MutableSong::setArtist; case MPD_TAG_ALBUM: - return &MPD::Song::SetAlbum; + return &MPD::MutableSong::setAlbum; case MPD_TAG_ALBUM_ARTIST: - return &MPD::Song::SetAlbumArtist; + return &MPD::MutableSong::setAlbumArtist; case MPD_TAG_TITLE: - return &MPD::Song::SetTitle; + return &MPD::MutableSong::setTitle; case MPD_TAG_TRACK: - return &MPD::Song::SetTrack; + return &MPD::MutableSong::setTrack; case MPD_TAG_GENRE: - return &MPD::Song::SetGenre; + return &MPD::MutableSong::setGenre; case MPD_TAG_DATE: - return &MPD::Song::SetDate; + return &MPD::MutableSong::setDate; case MPD_TAG_COMPOSER: - return &MPD::Song::SetComposer; + return &MPD::MutableSong::setComposer; case MPD_TAG_PERFORMER: - return &MPD::Song::SetPerformer; + return &MPD::MutableSong::setPerformer; case MPD_TAG_COMMENT: - return &MPD::Song::SetComment; + return &MPD::MutableSong::setComment; case MPD_TAG_DISC: - return &MPD::Song::SetDisc; + return &MPD::MutableSong::setDisc; default: return 0; } diff --git a/src/conv.h b/src/conv.h index 78c9d2fc..f0dc75c6 100644 --- a/src/conv.h +++ b/src/conv.h @@ -27,6 +27,7 @@ #include "numeric_conversions.h" #include "actions.h" #include "window.h" +#include "mutable_song.h" #include "song.h" template inline size_t static_strlen(const char (&)[N]) @@ -55,7 +56,7 @@ mpd_tag_type IntoTagItem(char); MPD::Song::GetFunction toGetFunction(char c); #ifdef HAVE_TAGLIB_H -MPD::Song::SetFunction IntoSetFunction(mpd_tag_type); +MPD::MutableSong::SetFunction IntoSetFunction(mpd_tag_type); #endif // HAVE_TAGLIB_H std::string Shorten(const std::basic_string &s, size_t max_length); diff --git a/src/display.cpp b/src/display.cpp index d7ebfbda..d3725574 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -336,7 +336,7 @@ void Display::Songs(const MPD::Song &s, void *data, Menu *menu) *menu << fmtUnderlineEnd; } -void Display::Tags(const MPD::Song &s, void *data, Menu *menu) +void Display::Tags(const MPD::MutableSong &s, void *data, Menu *menu) { size_t i = static_cast *>(data)->Choice(); if (i < 11) @@ -345,12 +345,10 @@ void Display::Tags(const MPD::Song &s, void *data, Menu *menu) } else if (i == 12) { - // FIXME - /*if (s.GetNewName().empty()) + if (s.getNewURI().empty()) *menu << s.getName(); else - *menu << s.getName() << Config.color2 << " -> " << clEnd << s.GetNewName(); - */ + *menu << s.getName() << Config.color2 << " -> " << clEnd << s.getNewURI(); } } diff --git a/src/display.h b/src/display.h index 3c4a5238..474b7dde 100644 --- a/src/display.h +++ b/src/display.h @@ -51,7 +51,7 @@ namespace Display void Songs(const MPD::Song &, void *, Menu *); - void Tags(const MPD::Song &, void *, Menu *); + void Tags(const MPD::MutableSong &, void *, Menu *); void Outputs(const MPD::Output &, void *, Menu *); diff --git a/src/helpers.cpp b/src/helpers.cpp index b854f90a..26425c97 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -365,24 +365,16 @@ void UpdateSongList(Menu *menu) } #ifdef HAVE_TAGLIB_H -std::string FindSharedDir(Menu *menu) -{ - MPD::SongList list; - for (size_t i = 0; i < menu->Size(); ++i) - list.push_back(&(*menu)[i]); - return FindSharedDir(list); -} - std::string FindSharedDir(const MPD::SongList &v) { if (v.empty()) // this should never happen, but in case... FatalError("empty SongList passed to FindSharedDir(const SongList &)!"); size_t i = -1; - std::string first = v.front()->GetDirectory(); + std::string first = v.front().getDirectory(); for (MPD::SongList::const_iterator it = ++v.begin(); it != v.end(); ++it) { size_t j = 0; - std::string dir = (*it)->GetDirectory(); + std::string dir = it->getDirectory(); size_t length = std::min(first.length(), dir.length()); while (!first.compare(j, 1, dir, j, 1) && j < length && j < i) ++j; diff --git a/src/helpers.h b/src/helpers.h index e23474d8..88fcf76a 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -220,11 +220,20 @@ std::string Timestamp(time_t t); void UpdateSongList(Menu *); +std::string FindSharedDir(const std::string &, const std::string &); #ifdef HAVE_TAGLIB_H -std::string FindSharedDir(Menu *); +template std::string FindSharedDir(Menu *menu) +{ + assert(!menu->Empty()); + std::string dir; + dir = (*menu)[0].getDirectory(); + for (size_t i = 1; i < menu->Size(); ++i) + dir = FindSharedDir(dir, (*menu)[i].getDirectory()); + return dir; +} std::string FindSharedDir(const MPD::SongList &); #endif // HAVE_TAGLIB_H -std::string FindSharedDir(const std::string &, const std::string &); + std::string ExtractTopName(const std::string &); std::string PathGoDownOneLevel(const std::string &path); diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index 8e52e271..9d9aba5a 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -1232,6 +1232,19 @@ void MPD::Connection::GetDirectories(const std::string &path, TagList &v) GoIdle(); } +void MPD::Connection::GetSongs(const std::string &path, SongList &v) +{ + if (!itsConnection) + return; + assert(!isCommandsListEnabled); + GoBusy(); + mpd_send_list_meta(itsConnection, path.c_str()); + while (mpd_song *s = mpd_recv_song(itsConnection)) + v.push_back(Song(s)); + mpd_response_finish(itsConnection); + GoIdle(); +} + void MPD::Connection::GetOutputs(std::function f) { if (!itsConnection) diff --git a/src/mutable_song.cpp b/src/mutable_song.cpp new file mode 100644 index 00000000..1e301b5b --- /dev/null +++ b/src/mutable_song.cpp @@ -0,0 +1,197 @@ +/*************************************************************************** + * 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 "mutable_song.h" +#include "string_utilities.h" + +namespace MPD {// + +std::string MutableSong::getArtist(unsigned idx) const +{ + return getTag(MPD_TAG_ARTIST, [this, idx](){ return Song::getArtist(idx); }, idx); +} + +std::string MutableSong::getTitle(unsigned idx) const +{ + return getTag(MPD_TAG_TITLE, [this, idx](){ return Song::getTitle(idx); }, idx); +} + +std::string MutableSong::getAlbum(unsigned idx) const +{ + return getTag(MPD_TAG_ALBUM, [this, idx](){ return Song::getAlbum(idx); }, idx); +} + +std::string MutableSong::getAlbumArtist(unsigned idx) const +{ + return getTag(MPD_TAG_ALBUM_ARTIST, [this, idx](){ return Song::getAlbumArtist(idx); }, idx); +} + +std::string MutableSong::getTrack(unsigned idx) const +{ + std::string track = getTag(MPD_TAG_TRACK, [this, idx](){ return Song::getTrack(idx); }, idx); + if ((track.length() == 1 && track[0] != '0') + || (track.length() > 3 && track[1] == '/')) + return "0"+track; + else + return track; +} + +std::string MutableSong::getDate(unsigned idx) const +{ + return getTag(MPD_TAG_DATE, [this, idx](){ return Song::getDate(idx); }, idx); +} + +std::string MutableSong::getGenre(unsigned idx) const +{ + return getTag(MPD_TAG_GENRE, [this, idx](){ return Song::getGenre(idx); }, idx); +} + +std::string MutableSong::getComposer(unsigned idx) const +{ + return getTag(MPD_TAG_COMPOSER, [this, idx](){ return Song::getComposer(idx); }, idx); +} + +std::string MutableSong::getPerformer(unsigned idx) const +{ + return getTag(MPD_TAG_PERFORMER, [this, idx](){ return Song::getPerformer(idx); }, idx); +} + +std::string MutableSong::getDisc(unsigned idx) const +{ + return getTag(MPD_TAG_DISC, [this, idx](){ return Song::getDisc(idx); }, idx); +} + +std::string MutableSong::getComment(unsigned idx) const +{ + return getTag(MPD_TAG_COMMENT, [this, idx](){ return Song::getComment(idx); }, idx); +} + +void MutableSong::setArtist(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_ARTIST, Song::getArtist(idx), value, idx); +} + +void MutableSong::setTitle(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_TITLE, Song::getTitle(idx), value, idx); +} + +void MutableSong::setAlbum(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_ALBUM, Song::getAlbum(idx), value, idx); +} + +void MutableSong::setAlbumArtist(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_ALBUM_ARTIST, Song::getAlbumArtist(idx), value, idx); +} + +void MutableSong::setTrack(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_TRACK, Song::getTrack(idx), value, idx); +} + +void MutableSong::setDate(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_DATE, Song::getDate(idx), value, idx); +} + +void MutableSong::setGenre(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_GENRE, Song::getGenre(idx), value, idx); +} + +void MutableSong::setComposer(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_COMPOSER, Song::getComposer(idx), value, idx); +} + +void MutableSong::setPerformer(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_PERFORMER, Song::getPerformer(idx), value, idx); +} + +void MutableSong::setDisc(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_DISC, Song::getDisc(idx), value, idx); +} + +void MutableSong::setComment(const std::string &value, unsigned idx) +{ + replaceTag(MPD_TAG_COMMENT, Song::getComment(idx), value, idx); +} + +const std::string &MutableSong::getNewURI() const +{ + return m_uri; +} + +void MutableSong::setNewURI(const std::string &value) +{ + std::string orig_uri = getURI(); + if (orig_uri == value) + m_uri.clear(); + else + m_uri = value; +} + +void MutableSong::setTag(SetFunction set, const std::string &value, const std::string &delimiter) +{ + auto tags = split(value, delimiter); + for (size_t i = 0; i < tags.size(); ++i) + (this->*set)(tags[i], i); +} + +bool MutableSong::isModified() const +{ + return !m_uri.empty() && !m_tags.empty(); +} + +void MutableSong::clearModifications() +{ + m_uri.clear(); + m_tags.clear(); +} + +std::string MutableSong::getTag(mpd_tag_type tag_type, std::function orig_value, unsigned idx) const +{ + auto it = m_tags.find(Tag(tag_type, idx)); + std::string result; + if (it == m_tags.end()) + result = orig_value(); + else + result = it->second; + return result; +} + +void MutableSong::replaceTag(mpd_tag_type tag_type, std::string &&orig_value, const std::string &value, unsigned idx) +{ + Tag tag(tag_type, idx); + if (value == orig_value) + { + auto it = m_tags.find(tag); + if (it != m_tags.end()) + m_tags.erase(it); + } + else + m_tags[tag] = value; +} + +} diff --git a/src/mutable_song.h b/src/mutable_song.h new file mode 100644 index 00000000..014be9f8 --- /dev/null +++ b/src/mutable_song.h @@ -0,0 +1,97 @@ +/*************************************************************************** + * 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 _EDITABLE_SONG_H +#define _EDITABLE_SONG_H + +#include +#include "song.h" + +namespace MPD {// + +struct MutableSong : public Song +{ + typedef void (MutableSong::*SetFunction)(const std::string &, unsigned); + + MutableSong() { } + MutableSong(Song s) : Song(s) { } + + virtual std::string getArtist(unsigned idx = 0) const; + virtual std::string getTitle(unsigned idx = 0) const; + virtual std::string getAlbum(unsigned idx = 0) const; + virtual std::string getAlbumArtist(unsigned idx = 0) const; + virtual std::string getTrack(unsigned idx = 0) const; + virtual std::string getDate(unsigned idx = 0) const; + virtual std::string getGenre(unsigned idx = 0) const; + virtual std::string getComposer(unsigned idx = 0) const; + virtual std::string getPerformer(unsigned idx = 0) const; + virtual std::string getDisc(unsigned idx = 0) const; + virtual std::string getComment(unsigned idx = 0) const; + + void setArtist(const std::string &value, unsigned idx = 0); + void setTitle(const std::string &value, unsigned idx = 0); + void setAlbum(const std::string &value, unsigned idx = 0); + void setAlbumArtist(const std::string &value, unsigned idx = 0); + void setTrack(const std::string &value, unsigned idx = 0); + void setDate(const std::string &value, unsigned idx = 0); + void setGenre(const std::string &value, unsigned idx = 0); + void setComposer(const std::string &value, unsigned idx = 0); + void setPerformer(const std::string &value, unsigned idx = 0); + void setDisc(const std::string &value, unsigned idx = 0); + void setComment(const std::string &value, unsigned idx = 0); + + const std::string &getNewURI() const; + void setNewURI(const std::string &value); + + void setTag(SetFunction set, const std::string &value, const std::string &delimiter = ""); + + bool isModified() const; + void clearModifications(); + +private: + struct Tag + { + Tag(mpd_tag_type type_, unsigned idx_) : m_type(type_), m_idx(idx_) { } + + mpd_tag_type type() const { return m_type; } + unsigned idx() const { return m_idx; } + + bool operator<(const Tag &t) const + { + if (m_type != t.m_type) + return m_type < t.m_type; + return m_idx < t.m_idx; + } + + private: + mpd_tag_type m_type; + unsigned m_idx; + }; + + std::string getTag(mpd_tag_type tag_type, std::function orig_value, unsigned idx) const; + void replaceTag(mpd_tag_type tag_type, std::string &&orig_value, const std::string &value, unsigned idx); + + std::string m_uri; + std::map m_tags; +}; + +} + +#endif // _EDITABLE_SONG_H diff --git a/src/song.cpp b/src/song.cpp index b07f4c4b..fde1619c 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -136,14 +136,11 @@ std::string Song::getTrack(unsigned idx) const std::string Song::getTrackNumber(unsigned idx) const { assert(pimpl); - std::string track = pimpl->getTag(MPD_TAG_TRACK, idx); + std::string track = getTrack(idx); size_t slash = track.find('/'); if (slash != std::string::npos) track.resize(slash); - if (track.length() == 1 && track[0] != '0') - return "0"+track; - else - return track; + return track; } std::string Song::getDate(unsigned idx) const diff --git a/src/song.h b/src/song.h index 2fe27256..b488f681 100644 --- a/src/song.h +++ b/src/song.h @@ -36,39 +36,40 @@ struct Song Song() { } Song(mpd_song *s); - std::string getURI(unsigned idx = 0) const; - std::string getName(unsigned idx = 0) const; - std::string getDirectory(unsigned idx = 0) const; - std::string getArtist(unsigned idx = 0) const; - std::string getTitle(unsigned idx = 0) const; - std::string getAlbum(unsigned idx = 0) const; - std::string getAlbumArtist(unsigned idx = 0) const; - std::string getTrack(unsigned idx = 0) const; - std::string getTrackNumber(unsigned idx = 0) const; - std::string getDate(unsigned idx = 0) const; - std::string getGenre(unsigned idx = 0) const; - std::string getComposer(unsigned idx = 0) const; - std::string getPerformer(unsigned idx = 0) const; - std::string getDisc(unsigned idx = 0) const; - std::string getComment(unsigned idx = 0) const; - std::string getLength(unsigned idx = 0) const; - std::string getPriority(unsigned idx = 0) const; + virtual std::string getURI(unsigned idx = 0) const; + virtual std::string getName(unsigned idx = 0) const; + virtual std::string getDirectory(unsigned idx = 0) const; + virtual std::string getArtist(unsigned idx = 0) const; + virtual std::string getTitle(unsigned idx = 0) const; + virtual std::string getAlbum(unsigned idx = 0) const; + virtual std::string getAlbumArtist(unsigned idx = 0) const; + virtual std::string getTrack(unsigned idx = 0) const; + virtual std::string getTrackNumber(unsigned idx = 0) const; + virtual std::string getDate(unsigned idx = 0) const; + virtual std::string getGenre(unsigned idx = 0) const; + virtual std::string getComposer(unsigned idx = 0) const; + virtual std::string getPerformer(unsigned idx = 0) const; + virtual std::string getDisc(unsigned idx = 0) const; + virtual std::string getComment(unsigned idx = 0) const; + virtual std::string getLength(unsigned idx = 0) const; + virtual std::string getPriority(unsigned idx = 0) const; - std::string getTags(GetFunction f, const std::string &tag_separator = ", ") const; + virtual std::string getTags(GetFunction f, const std::string &tag_separator = ", ") const; - unsigned getHash() const; - unsigned getDuration() const; - unsigned getPosition() const; - unsigned getID() const; - unsigned getPrio() const; - time_t getMTime() const; + virtual unsigned getHash() const; + virtual unsigned getDuration() const; + virtual unsigned getPosition() const; + virtual unsigned getID() const; + virtual unsigned getPrio() const; + virtual time_t getMTime() const; - bool isFromDatabase() const; - bool isStream() const; + virtual bool isFromDatabase() const; + virtual bool isStream() const; - bool empty() const; + virtual bool empty() const; - std::string toString(const std::string &fmt, const std::string &tag_separator = ", ", const std::string &escape_chars = "") const; + virtual std::string toString(const std::string &fmt, const std::string &tag_separator = ", ", + const std::string &escape_chars = "") const; static std::string ShowTime(unsigned length); static bool isFormatOk(const std::string &type, const std::string &fmt); @@ -76,7 +77,8 @@ struct Song static const char FormatEscapeCharacter = 1; private: - std::string ParseFormat(std::string::const_iterator &it, const std::string &tag_separator, const std::string &escape_chars) const; + std::string ParseFormat(std::string::const_iterator &it, const std::string &tag_separator, + const std::string &escape_chars) const; std::shared_ptr pimpl; }; diff --git a/src/song_info.cpp b/src/song_info.cpp index beff130a..b065b157 100644 --- a/src/song_info.cpp +++ b/src/song_info.cpp @@ -29,18 +29,18 @@ SongInfo *mySongInfo = new SongInfo; const SongInfo::Metadata SongInfo::Tags[] = { - { "Title", &MPD::Song::getTitle, }, - { "Artist", &MPD::Song::getArtist, }, - { "Album Artist", &MPD::Song::getAlbumArtist, }, - { "Album", &MPD::Song::getAlbum, }, - { "Date", &MPD::Song::getDate, }, - { "Track", &MPD::Song::getTrack, }, - { "Genre", &MPD::Song::getGenre, }, - { "Composer", &MPD::Song::getComposer, }, - { "Performer", &MPD::Song::getPerformer, }, - { "Disc", &MPD::Song::getDisc, }, - { "Comment", &MPD::Song::getComment, }, - { 0, 0, } + { "Title", &MPD::Song::getTitle, &MPD::MutableSong::setTitle }, + { "Artist", &MPD::Song::getArtist, &MPD::MutableSong::setArtist }, + { "Album Artist", &MPD::Song::getAlbumArtist, &MPD::MutableSong::setAlbumArtist }, + { "Album", &MPD::Song::getAlbum, &MPD::MutableSong::setAlbum }, + { "Date", &MPD::Song::getDate, &MPD::MutableSong::setDate }, + { "Track", &MPD::Song::getTrack, &MPD::MutableSong::setTrack }, + { "Genre", &MPD::Song::getGenre, &MPD::MutableSong::setGenre }, + { "Composer", &MPD::Song::getComposer, &MPD::MutableSong::setComposer }, + { "Performer", &MPD::Song::getPerformer, &MPD::MutableSong::setPerformer }, + { "Disc", &MPD::Song::getDisc, &MPD::MutableSong::setDisc }, + { "Comment", &MPD::Song::getComment, &MPD::MutableSong::setComment }, + { 0, 0, 0 } }; void SongInfo::Init() @@ -105,8 +105,6 @@ void SongInfo::PrepareSong(MPD::Song &s) path_to_file += Config.mpd_music_dir; path_to_file += s.getURI(); TagLib::FileRef f(path_to_file.c_str()); - if (!f.isNull()) - s.SetComment(f.tag()->comment().to8Bit(1)); # endif // HAVE_TAGLIB_H *w << fmtBold << Config.color1 << U("Filename: ") << fmtBoldEnd << Config.color2 << s.getName() << '\n' << clEnd; diff --git a/src/song_info.h b/src/song_info.h index 09c1272f..b9ae4eb5 100644 --- a/src/song_info.h +++ b/src/song_info.h @@ -31,7 +31,7 @@ class SongInfo : public Screen { const char *Name; MPD::Song::GetFunction Get; - //MPD::Song::SetFunction Set; + MPD::MutableSong::SetFunction Set; }; virtual void SwitchTo(); diff --git a/src/string_utilities.cpp b/src/string_utilities.cpp new file mode 100644 index 00000000..cbedba95 --- /dev/null +++ b/src/string_utilities.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * 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 +#include "string_utilities.h" + +std::vector split(const std::string &s, const std::string &delimiter) +{ + if (delimiter.empty()) + return { s }; + std::vector result; + size_t i = 0, j = 0; + while (true) + { + i = j; + j = s.find(delimiter, i); + if (j == std::string::npos) + break; + else + result.push_back(s.substr(i, j-i)); + j += delimiter.length(); + } + result.push_back(s.substr(i)); + return result; +} diff --git a/src/string_utilities.h b/src/string_utilities.h new file mode 100644 index 00000000..6cee0329 --- /dev/null +++ b/src/string_utilities.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * 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 _STRING_UTILITIES +#define _STRING_UTILITIES + +#include +#include + +std::vector split(const std::string &s, const std::string &delimiter); + +#endif // _STRING_UTILITIES diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index f07d7308..eb0868d2 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -103,7 +103,7 @@ void TagEditor::Init() TagTypes->AddOption("Reset"); TagTypes->AddOption("Save"); - Tags = new Menu(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, Config.titles_visibility ? "Tags" : "", Config.main_color, brNone); + Tags = new Menu(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, Config.titles_visibility ? "Tags" : "", Config.main_color, brNone); Tags->HighlightColor(Config.main_highlight_color); Tags->CyclicScrolling(Config.use_cyclic_scrolling); Tags->CenteredCursor(Config.centered_cursor); @@ -249,13 +249,11 @@ void TagEditor::Update() MPD::SongList l; Mpd.StartSearch(1); Mpd.AddSearch(MPD_TAG_ALBUM, *it); - Mpd.CommitSearch(l); + Mpd.CommitSearchSongs([&l](MPD::Song &&s) { + l.push_back(s); + }); if (!l.empty()) - { - l[0]->Localize(); - Albums->AddOption(std::make_pair(l[0]->toString(Config.tag_editor_album_format), *it)); - } - MPD::FreeSongList(l); + Albums->AddOption(std::make_pair(l[0].toString(Config.tag_editor_album_format), *it)); } Mpd.BlockIdle(0); Albums->Sort(); @@ -301,26 +299,21 @@ void TagEditor::Update() { Mpd.StartSearch(1); Mpd.AddSearch(MPD_TAG_ALBUM, Albums->Current().second); - Mpd.CommitSearch(list); - sort(list.begin(), list.end(), CaseInsensitiveSorting()); - for (MPD::SongList::iterator it = list.begin(); it != list.end(); ++it) - { - (*it)->Localize(); - Tags->AddOption(**it); - } + Mpd.CommitSearchSongs([&list](MPD::Song &&s) { + list.push_back(s); + }); + std::sort(list.begin(), list.end(), CaseInsensitiveSorting()); + for (auto it = list.begin(); it != list.end(); ++it) + Tags->AddOption(*it); } } else { Mpd.GetSongs(Dirs->Current().second, list); - sort(list.begin(), list.end(), CaseInsensitiveSorting()); - for (MPD::SongList::const_iterator it = list.begin(); it != list.end(); ++it) - { - (*it)->Localize(); - Tags->AddOption(**it); - } + std::sort(list.begin(), list.end(), CaseInsensitiveSorting()); + for (auto it = list.begin(); it != list.end(); ++it) + Tags->AddOption(*it); } - MPD::FreeSongList(list); Tags->Window::Clear(); Tags->Refresh(); } @@ -368,20 +361,20 @@ void TagEditor::EnterPressed() // prepare additional windows FParserLegend->Clear(); - *FParserLegend << "%a - artist\n"; - *FParserLegend << "%A - album artist\n"; - *FParserLegend << "%t - title\n"; - *FParserLegend << "%b - album\n"; - *FParserLegend << "%y - date\n"; - *FParserLegend << "%n - track number\n"; - *FParserLegend << "%g - genre\n"; - *FParserLegend << "%c - composer\n"; - *FParserLegend << "%p - performer\n"; - *FParserLegend << "%d - disc\n"; - *FParserLegend << "%C - comment\n\n"; - *FParserLegend << fmtBold << "Files:\n" << fmtBoldEnd; - for (MPD::SongList::const_iterator it = EditedSongs.begin(); it != EditedSongs.end(); ++it) - *FParserLegend << Config.color2 << " * " << clEnd << (*it)->getName() << "\n"; + *FParserLegend << U("%a - artist\n"); + *FParserLegend << U("%A - album artist\n"); + *FParserLegend << U("%t - title\n"); + *FParserLegend << U("%b - album\n"); + *FParserLegend << U("%y - date\n"); + *FParserLegend << U("%n - track number\n"); + *FParserLegend << U("%g - genre\n"); + *FParserLegend << U("%c - composer\n"); + *FParserLegend << U("%p - performer\n"); + *FParserLegend << U("%d - disc\n"); + *FParserLegend << U("%C - comment\n\n"); + *FParserLegend << fmtBold << U("Files:\n") << fmtBoldEnd; + for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it) + *FParserLegend << Config.color2 << U(" * ") << clEnd << (*it)->getName() << '\n'; FParserLegend->Flush(); if (!Patterns.empty()) @@ -435,15 +428,15 @@ void TagEditor::EnterPressed() bool success = 1; ShowMessage("Parsing..."); FParserPreview->Clear(); - for (MPD::SongList::iterator it = EditedSongs.begin(); it != EditedSongs.end(); ++it) + for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it) { - MPD::Song &s = **it; + MPD::MutableSong &s = **it; if (FParserDialog->Choice() == 0) // get tags from filename { if (FParserUsePreview) { - *FParserPreview << fmtBold << s.getName() << ":\n" << fmtBoldEnd; - *FParserPreview << ParseFilename(s, Config.pattern, FParserUsePreview) << "\n"; + *FParserPreview << fmtBold << s.getName() << U(":\n") << fmtBoldEnd; + *FParserPreview << ParseFilename(s, Config.pattern, FParserUsePreview) << '\n'; } else ParseFilename(s, Config.pattern, FParserUsePreview); @@ -461,13 +454,13 @@ void TagEditor::EnterPressed() success = 0; } if (!FParserUsePreview) - s.SetNewName(new_file + extension); - *FParserPreview << file << Config.color2 << " -> " << clEnd; + s.setNewURI(new_file + extension); + *FParserPreview << file << Config.color2 << U(" -> ") << clEnd; if (new_file.empty()) *FParserPreview << Config.empty_tags_color << Config.empty_tag << clEnd; else *FParserPreview << new_file << extension; - *FParserPreview << "\n\n"; + *FParserPreview << '\n' << '\n'; if (!success) break; } @@ -519,7 +512,7 @@ void TagEditor::EnterPressed() { std::vector selected; Tags->GetSelected(selected); - for (std::vector::const_iterator it = selected.begin(); it != selected.end(); ++it) + for (auto it = selected.begin(); it != selected.end(); ++it) EditedSongs.push_back(&(*Tags)[*it]); } else @@ -533,13 +526,13 @@ void TagEditor::EnterPressed() bool yes = Action::AskYesNoQuestion("Number tracks?", TraceMpdStatus); if (yes) { - MPD::SongList::iterator it = EditedSongs.begin(); + auto it = EditedSongs.begin(); for (unsigned i = 1; i <= EditedSongs.size(); ++i, ++it) { if (Config.tag_editor_extended_numeration) - (*it)->SetTrack(IntoStr(i) + "/" + IntoStr(EditedSongs.size())); + (*it)->setTrack(unsignedIntTo::apply(i) + "/" + unsignedIntTo::apply(EditedSongs.size())); else - (*it)->SetTrack(i); + (*it)->setTrack(unsignedIntTo::apply(i)); } ShowMessage("Tracks numbered"); } @@ -551,15 +544,15 @@ void TagEditor::EnterPressed() if (id < 11) { MPD::Song::GetFunction get = SongInfo::Tags[id].Get; - MPD::Song::SetFunction set = SongInfo::Tags[id].Set; + MPD::MutableSong::SetFunction set = SongInfo::Tags[id].Set; if (id > 0 && w == TagTypes) { LockStatusbar(); Statusbar() << fmtBold << TagTypes->Current() << fmtBoldEnd << ": "; std::string new_tag = wFooter->GetString(Tags->Current().getTags(get)); UnlockStatusbar(); - for (MPD::SongList::iterator it = EditedSongs.begin(); it != EditedSongs.end(); ++it) - (*it)->SetTags(set, new_tag); + for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it) + (*it)->setTag(set, new_tag); } else if (w == Tags) { @@ -568,7 +561,7 @@ void TagEditor::EnterPressed() std::string new_tag = wFooter->GetString(Tags->Current().getTags(get)); UnlockStatusbar(); if (new_tag != Tags->Current().getTags(get)) - Tags->Current().SetTags(set, new_tag); + Tags->Current().setTag(set, new_tag); Tags->Scroll(wDown); } } @@ -588,8 +581,8 @@ void TagEditor::EnterPressed() } else if (w == Tags) { - MPD::Song &s = Tags->Current(); - std::string old_name = s.GetNewName().empty() ? s.getName() : s.GetNewName(); + MPD::MutableSong &s = Tags->Current(); + std::string old_name = s.getNewURI().empty() ? s.getName() : s.getNewURI(); size_t last_dot = old_name.rfind("."); std::string extension = old_name.substr(last_dot); old_name = old_name.substr(0, last_dot); @@ -598,21 +591,21 @@ void TagEditor::EnterPressed() std::string new_name = wFooter->GetString(old_name); UnlockStatusbar(); if (!new_name.empty() && new_name != old_name) - s.SetNewName(new_name + extension); + s.setNewURI(new_name + extension); Tags->Scroll(wDown); } } else if (id == 12) // capitalize first letters { ShowMessage("Processing..."); - for (MPD::SongList::iterator it = EditedSongs.begin(); it != EditedSongs.end(); ++it) + for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it) CapitalizeFirstLetters(**it); ShowMessage("Done"); } else if (id == 13) // lower all letters { ShowMessage("Processing..."); - for (MPD::SongList::iterator it = EditedSongs.begin(); it != EditedSongs.end(); ++it) + for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it) LowerAllLetters(**it); ShowMessage("Done"); } @@ -625,7 +618,7 @@ void TagEditor::EnterPressed() { bool success = 1; ShowMessage("Writing changes..."); - for (MPD::SongList::iterator it = EditedSongs.begin(); it != EditedSongs.end(); ++it) + for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it) { ShowMessage("Writing tags in \"%s\"...", (*it)->getName().c_str()); if (!WriteTags(**it)) @@ -644,7 +637,7 @@ void TagEditor::EnterPressed() w->Refresh(); w = LeftColumn; LeftColumn->HighlightColor(Config.active_column_color); - Mpd.UpdateDirectory(locale_to_utf_cpy(FindSharedDir(Tags))); + Mpd.UpdateDirectory(FindSharedDir(Tags)); } else Tags->Clear(); @@ -775,8 +768,8 @@ void TagEditor::GetSelectedSongs(MPD::SongList &v) Tags->GetSelected(selected); if (selected.empty()) selected.push_back(Tags->Choice()); - for (std::vector::const_iterator it = selected.begin(); it != selected.end(); ++it) - v.push_back(new MPD::Song(Tags->at(*it))); + for (auto it = selected.begin(); it != selected.end(); ++it) + v.push_back(static_cast((*Tags)[*it])); } void TagEditor::ApplyFilter(const std::string &s) @@ -902,7 +895,7 @@ void TagEditor::LocateSong(const MPD::Song &s) if (myScreen == this) return; - if (s.GetDirectory().empty()) + if (s.getDirectory().empty()) return; if (LeftColumn == Albums) @@ -917,9 +910,9 @@ void TagEditor::LocateSong(const MPD::Song &s) SwitchTo(); // go to right directory - if (itsBrowsedDir != s.GetDirectory()) + if (itsBrowsedDir != s.getDirectory()) { - itsBrowsedDir = s.GetDirectory(); + itsBrowsedDir = s.getDirectory(); size_t last_slash = itsBrowsedDir.rfind('/'); if (last_slash != std::string::npos) itsBrowsedDir = itsBrowsedDir.substr(0, last_slash); @@ -934,7 +927,7 @@ void TagEditor::LocateSong(const MPD::Song &s) Dirs->Reset(); // go to the first pos, which is "." (music dir root) // highlight directory we need and get files from it - std::string dir = ExtractTopName(s.GetDirectory()); + std::string dir = ExtractTopName(s.getDirectory()); for (size_t i = 0; i < Dirs->Size(); ++i) { if ((*Dirs)[i].first == dir) @@ -961,7 +954,7 @@ void TagEditor::LocateSong(const MPD::Song &s) } } -void TagEditor::ReadTags(MPD::Song &s) +void TagEditor::ReadTags(MPD::MutableSong &s) { TagLib::FileRef f(s.getURI().c_str()); if (f.isNull()) @@ -969,20 +962,20 @@ void TagEditor::ReadTags(MPD::Song &s) TagLib::MPEG::File *mpegf = dynamic_cast(f.file()); - s.SetArtist(f.tag()->artist().to8Bit(1)); - s.SetTitle(f.tag()->title().to8Bit(1)); - s.SetAlbum(f.tag()->album().to8Bit(1)); - s.SetTrack(IntoStr(f.tag()->track())); - s.SetDate(IntoStr(f.tag()->year())); - s.SetGenre(f.tag()->genre().to8Bit(1)); + s.setArtist(f.tag()->artist().to8Bit(1)); + s.setTitle(f.tag()->title().to8Bit(1)); + s.setAlbum(f.tag()->album().to8Bit(1)); + s.setTrack(intTo::apply(f.tag()->track())); + s.setDate(intTo::apply(f.tag()->year())); + s.setGenre(f.tag()->genre().to8Bit(1)); if (mpegf) { - s.SetAlbumArtist(!mpegf->ID3v2Tag()->frameListMap()["TPE2"].isEmpty() ? mpegf->ID3v2Tag()->frameListMap()["TPE2"].front()->toString().to8Bit(1) : ""); - s.SetComposer(!mpegf->ID3v2Tag()->frameListMap()["TCOM"].isEmpty() ? mpegf->ID3v2Tag()->frameListMap()["TCOM"].front()->toString().to8Bit(1) : ""); - s.SetPerformer(!mpegf->ID3v2Tag()->frameListMap()["TOPE"].isEmpty() ? mpegf->ID3v2Tag()->frameListMap()["TOPE"].front()->toString().to8Bit(1) : ""); - s.SetDisc(!mpegf->ID3v2Tag()->frameListMap()["TPOS"].isEmpty() ? mpegf->ID3v2Tag()->frameListMap()["TPOS"].front()->toString().to8Bit(1) : ""); + s.setAlbumArtist(!mpegf->ID3v2Tag()->frameListMap()["TPE2"].isEmpty() ? mpegf->ID3v2Tag()->frameListMap()["TPE2"].front()->toString().to8Bit(1) : ""); + s.setComposer(!mpegf->ID3v2Tag()->frameListMap()["TCOM"].isEmpty() ? mpegf->ID3v2Tag()->frameListMap()["TCOM"].front()->toString().to8Bit(1) : ""); + s.setPerformer(!mpegf->ID3v2Tag()->frameListMap()["TOPE"].isEmpty() ? mpegf->ID3v2Tag()->frameListMap()["TOPE"].front()->toString().to8Bit(1) : ""); + s.setDisc(!mpegf->ID3v2Tag()->frameListMap()["TPOS"].isEmpty() ? mpegf->ID3v2Tag()->frameListMap()["TPOS"].front()->toString().to8Bit(1) : ""); } - s.SetComment(f.tag()->comment().to8Bit(1)); + s.setComment(f.tag()->comment().to8Bit(1)); } namespace @@ -997,7 +990,7 @@ namespace } } -void TagEditor::WriteXiphComments(const MPD::Song &s, TagLib::Ogg::XiphComment *tag) +void TagEditor::WriteXiphComments(const MPD::MutableSong &s, TagLib::Ogg::XiphComment *tag) { TagLib::StringList list; @@ -1019,7 +1012,7 @@ void TagEditor::WriteXiphComments(const MPD::Song &s, TagLib::Ogg::XiphComment * tag->addField("PERFORMER", *it, 0); } -bool TagEditor::WriteTags(MPD::Song &s) +bool TagEditor::WriteTags(MPD::MutableSong &s) { std::string path_to_file; bool file_is_from_db = s.isFromDatabase(); @@ -1072,12 +1065,12 @@ bool TagEditor::WriteTags(MPD::Song &s) if (!f.save()) return false; - if (!s.GetNewName().empty()) + if (!s.getNewURI().empty()) { std::string new_name; if (file_is_from_db) new_name += Config.mpd_music_dir; - new_name += s.GetDirectory() + "/" + s.GetNewName(); + new_name += s.getDirectory() + "/" + s.getNewURI(); locale_to_utf(new_name); if (rename(path_to_file.c_str(), new_name.c_str()) == 0 && !file_is_from_db) { @@ -1121,7 +1114,7 @@ std::string TagEditor::CapitalizeFirstLetters(const std::string &s) return result; } -void TagEditor::CapitalizeFirstLetters(MPD::Song &s) +void TagEditor::CapitalizeFirstLetters(MPD::MutableSong &s) { for (const SongInfo::Metadata *m = SongInfo::Tags; m->Name; ++m) { @@ -1131,7 +1124,7 @@ void TagEditor::CapitalizeFirstLetters(MPD::Song &s) } } -void TagEditor::LowerAllLetters(MPD::Song &s) +void TagEditor::LowerAllLetters(MPD::MutableSong &s) { for (const SongInfo::Metadata *m = SongInfo::Tags; m->Name; ++m) { @@ -1144,7 +1137,7 @@ void TagEditor::LowerAllLetters(MPD::Song &s) } } -void TagEditor::GetTagList(TagLib::StringList &list, const MPD::Song &s, MPD::Song::GetFunction f) +void TagEditor::GetTagList(TagLib::StringList &list, const MPD::MutableSong &s, MPD::Song::GetFunction f) { list.clear(); unsigned pos = 0; @@ -1152,14 +1145,14 @@ void TagEditor::GetTagList(TagLib::StringList &list, const MPD::Song &s, MPD::So list.append(ToWString(value)); } -std::string TagEditor::TagToString(const MPD::Song &s, void *data) +std::string TagEditor::TagToString(const MPD::MutableSong &s, void *data) { std::string result; size_t i = static_cast *>(data)->Choice(); if (i < 11) result = (s.*SongInfo::Tags[i].Get)(0); else if (i == 12) - result = s.GetNewName().empty() ? s.getName() : s.getName() + " -> " + s.GetNewName(); + result = s.getNewURI().empty() ? s.getName() : s.getName() + " -> " + s.getNewURI(); return result.empty() ? Config.empty_tag : result; } @@ -1191,45 +1184,45 @@ void TagEditor::SavePatternList() } } -MPD::Song::SetFunction TagEditor::IntoSetFunction(char c) +MPD::MutableSong::SetFunction TagEditor::IntoSetFunction(char c) { switch (c) { case 'a': - return &MPD::Song::SetArtist; + return &MPD::MutableSong::setArtist; case 'A': - return &MPD::Song::SetAlbumArtist; + return &MPD::MutableSong::setAlbumArtist; case 't': - return &MPD::Song::SetTitle; + return &MPD::MutableSong::setTitle; case 'b': - return &MPD::Song::SetAlbum; + return &MPD::MutableSong::setAlbum; case 'y': - return &MPD::Song::SetDate; + return &MPD::MutableSong::setDate; case 'n': - return &MPD::Song::SetTrack; + return &MPD::MutableSong::setTrack; case 'g': - return &MPD::Song::SetGenre; + return &MPD::MutableSong::setGenre; case 'c': - return &MPD::Song::SetComposer; + return &MPD::MutableSong::setComposer; case 'p': - return &MPD::Song::SetPerformer; + return &MPD::MutableSong::setPerformer; case 'd': - return &MPD::Song::SetDisc; + return &MPD::MutableSong::setDisc; case 'C': - return &MPD::Song::SetComment; + return &MPD::MutableSong::setComment; default: return 0; } } -std::string TagEditor::GenerateFilename(const MPD::Song &s, const std::string &pattern) +std::string TagEditor::GenerateFilename(const MPD::MutableSong &s, const std::string &pattern) { std::string result = s.toString(pattern); EscapeUnallowedChars(result); return result; } -std::string TagEditor::ParseFilename(MPD::Song &s, std::string mask, bool preview) +std::string TagEditor::ParseFilename(MPD::MutableSong &s, std::string mask, bool preview) { std::ostringstream result; std::vector separators; @@ -1274,9 +1267,9 @@ std::string TagEditor::ParseFilename(MPD::Song &s, std::string mask, bool previe if (!preview) { - MPD::Song::SetFunction set = IntoSetFunction(it->first); + MPD::MutableSong::SetFunction set = IntoSetFunction(it->first); if (set) - s.SetTags(set, it->second); + s.setTag(set, it->second); } else result << "%" << it->first << ": " << it->second << "\n"; diff --git a/src/tag_editor.h b/src/tag_editor.h index 9cb615b1..5c49b32e 100644 --- a/src/tag_editor.h +++ b/src/tag_editor.h @@ -21,9 +21,7 @@ #ifndef _TAG_EDITOR_H #define _TAG_EDITOR_H -#ifdef HAVE_CONFIG_H -# include -#endif +#include "config.h" #ifdef HAVE_TAGLIB_H @@ -79,13 +77,13 @@ class TagEditor : public Screen Menu *Albums; Menu *Dirs; Menu *TagTypes; - Menu *Tags; + Menu *Tags; /// NOTICE: this string is always in utf8, no need to convert it const std::string &CurrentDir() { return itsBrowsedDir; } - static void ReadTags(MPD::Song &); - static bool WriteTags(MPD::Song &); + static void ReadTags(MPD::MutableSong &); + static bool WriteTags(MPD::MutableSong &); protected: virtual void Init(); @@ -94,7 +92,7 @@ class TagEditor : public Screen private: void SetDimensions(size_t, size_t); - MPD::SongList EditedSongs; + std::vector EditedSongs; Menu *FParserDialog; Menu *FParser; Scrollpad *FParserHelper; @@ -103,18 +101,18 @@ class TagEditor : public Screen bool FParserUsePreview; static std::string CapitalizeFirstLetters(const std::string &); - static void CapitalizeFirstLetters(MPD::Song &); - static void LowerAllLetters(MPD::Song &); - static void GetTagList(TagLib::StringList &, const MPD::Song &, MPD::Song::GetFunction); - static void WriteXiphComments(const MPD::Song &, TagLib::Ogg::XiphComment *); + static void CapitalizeFirstLetters(MPD::MutableSong &); + static void LowerAllLetters(MPD::MutableSong &); + static void GetTagList(TagLib::StringList &, const MPD::MutableSong &, MPD::Song::GetFunction); + static void WriteXiphComments(const MPD::MutableSong &, TagLib::Ogg::XiphComment *); static void GetPatternList(); static void SavePatternList(); - static MPD::Song::SetFunction IntoSetFunction(char); - static std::string GenerateFilename(const MPD::Song &, const std::string &); - static std::string ParseFilename(MPD::Song &, std::string, bool); + static MPD::MutableSong::SetFunction IntoSetFunction(char); + static std::string GenerateFilename(const MPD::MutableSong &, const std::string &); + static std::string ParseFilename(MPD::MutableSong &, std::string, bool); - static std::string TagToString(const MPD::Song &, void *); + static std::string TagToString(const MPD::MutableSong &, void *); std::string itsBrowsedDir; std::string itsHighlightedDir; diff --git a/src/tiny_tag_editor.cpp b/src/tiny_tag_editor.cpp index 353d6e29..180b1a70 100644 --- a/src/tiny_tag_editor.cpp +++ b/src/tiny_tag_editor.cpp @@ -104,48 +104,42 @@ std::basic_string TinyTagEditor::Title() void TinyTagEditor::EnterPressed() { size_t option = w->Choice(); - MPD::Song &s = itsEdited; - LockStatusbar(); if (option < 19) // separator after comment { size_t pos = option-8; Statusbar() << fmtBold << SongInfo::Tags[pos].Name << ": " << fmtBoldEnd; - s.SetTags(SongInfo::Tags[pos].Set, Global::wFooter->GetString(s.getTags(SongInfo::Tags[pos].Get))); + itsEdited.setTag(SongInfo::Tags[pos].Set, Global::wFooter->GetString(itsEdited.getTags(SongInfo::Tags[pos].Get))); w->at(option).Clear(); w->at(option) << fmtBold << SongInfo::Tags[pos].Name << ':' << fmtBoldEnd << ' '; - ShowTag(w->at(option), s.getTags(SongInfo::Tags[pos].Get)); + ShowTag(w->at(option), itsEdited.getTags(SongInfo::Tags[pos].Get)); } else if (option == 20) { Statusbar() << fmtBold << "Filename: " << fmtBoldEnd; - std::string filename = s.GetNewName().empty() ? s.getName() : s.GetNewName(); + std::string filename = itsEdited.getNewURI().empty() ? itsEdited.getName() : itsEdited.getNewURI(); size_t dot = filename.rfind("."); std::string extension = filename.substr(dot); filename = filename.substr(0, dot); std::string new_name = Global::wFooter->GetString(filename); - s.SetNewName(new_name + extension); + itsEdited.setNewURI(new_name + extension); w->at(option).Clear(); - w->at(option) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << (s.GetNewName().empty() ? s.getName() : s.GetNewName()); + w->at(option) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << (itsEdited.getNewURI().empty() ? itsEdited.getName() : itsEdited.getNewURI()); } UnlockStatusbar(); if (option == 22) { ShowMessage("Updating tags..."); - if (TagEditor::WriteTags(s)) + if (TagEditor::WriteTags(itsEdited)) { ShowMessage("Tags updated"); - if (s.isFromDatabase()) - { - Mpd.UpdateDirectory(locale_to_utf_cpy(s.GetDirectory())); - if (myOldScreen == mySearcher) // songs from search engine are not updated automatically - *mySearcher->Main()->Current().second = s; - } + if (itsEdited.isFromDatabase()) + Mpd.UpdateDirectory(itsEdited.getDirectory()); else { if (myOldScreen == myPlaylist) - myPlaylist->Items->Current() = s; + myPlaylist->Items->Current() = itsEdited; else if (myOldScreen == myBrowser) myBrowser->GetDirectory(myBrowser->CurrentDir()); } @@ -182,19 +176,17 @@ void TinyTagEditor::SetEdited(const MPD::Song &s) bool TinyTagEditor::getTags() { - MPD::Song &s = itsEdited; - std::string path_to_file; - if (s.isFromDatabase()) + if (itsEdited.isFromDatabase()) path_to_file += Config.mpd_music_dir; - path_to_file += s.getURI(); + path_to_file += itsEdited.getURI(); TagLib::FileRef f(path_to_file.c_str()); if (f.isNull()) return false; - s.SetComment(f.tag()->comment().to8Bit(1)); + itsEdited.setComment(f.tag()->comment().to8Bit(1)); - std::string ext = s.getURI(); + std::string ext = itsEdited.getURI(); ext = ext.substr(ext.rfind(".")+1); ToLower(ext); @@ -222,11 +214,11 @@ bool TinyTagEditor::getTags() w->Highlight(8); - w->at(0) << fmtBold << Config.color1 << "Song name: " << fmtBoldEnd << Config.color2 << s.getName() << clEnd; + w->at(0) << fmtBold << Config.color1 << "Song name: " << fmtBoldEnd << Config.color2 << itsEdited.getName() << clEnd; w->at(1) << fmtBold << Config.color1 << "Location in DB: " << fmtBoldEnd << Config.color2; - ShowTag(w->at(1), s.GetDirectory()); + ShowTag(w->at(1), itsEdited.getDirectory()); w->at(1) << clEnd; - w->at(3) << fmtBold << Config.color1 << "Length: " << fmtBoldEnd << Config.color2 << s.getLength() << clEnd; + w->at(3) << fmtBold << Config.color1 << "Length: " << fmtBoldEnd << Config.color2 << itsEdited.getLength() << clEnd; w->at(4) << fmtBold << Config.color1 << "Bitrate: " << fmtBoldEnd << Config.color2 << f.audioProperties()->bitrate() << " kbps" << clEnd; w->at(5) << fmtBold << Config.color1 << "Sample rate: " << fmtBoldEnd << Config.color2 << f.audioProperties()->sampleRate() << " Hz" << clEnd; w->at(6) << fmtBold << Config.color1 << "Channels: " << fmtBoldEnd << Config.color2 << (f.audioProperties()->channels() == 1 ? "Mono" : "Stereo") << clDefault; @@ -235,10 +227,10 @@ bool TinyTagEditor::getTags() for (const SongInfo::Metadata *m = SongInfo::Tags; m->Name; ++m, ++pos) { w->at(pos) << fmtBold << m->Name << ":" << fmtBoldEnd << ' '; - ShowTag(w->at(pos), s.getTags(m->Get)); + ShowTag(w->at(pos), itsEdited.getTags(m->Get)); } - w->at(20) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << s.getName(); + w->at(20) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << itsEdited.getName(); w->at(22) << "Save"; w->at(23) << "Cancel"; diff --git a/src/tiny_tag_editor.h b/src/tiny_tag_editor.h index 1bc35fed..93872284 100644 --- a/src/tiny_tag_editor.h +++ b/src/tiny_tag_editor.h @@ -21,9 +21,7 @@ #ifndef _TINY_TAG_EDITOR_H #define _TINY_TAG_EDITOR_H -#ifdef HAVE_CONFIG_H -# include -#endif +#include "config.h" #ifdef HAVE_TAGLIB_H @@ -58,7 +56,7 @@ class TinyTagEditor : public Screen< Menu > private: bool getTags(); - MPD::Song itsEdited; + MPD::MutableSong itsEdited; static bool extendedTagsSupported(TagLib::File *); };