fix compilation --without-taglib

This commit is contained in:
Andrzej Rybczak
2012-08-29 09:07:20 +02:00
parent ddeec3aea0
commit 4cb0e2232a
22 changed files with 609 additions and 247 deletions

View File

@@ -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 \

View File

@@ -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");
}
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -27,6 +27,7 @@
#include "numeric_conversions.h"
#include "actions.h"
#include "window.h"
#include "mutable_song.h"
#include "song.h"
template <size_t N> 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<my_char_t> &s, size_t max_length);

View File

@@ -336,7 +336,7 @@ void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
*menu << fmtUnderlineEnd;
}
void Display::Tags(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
void Display::Tags(const MPD::MutableSong &s, void *data, Menu<MPD::MutableSong> *menu)
{
size_t i = static_cast<Menu<std::string> *>(data)->Choice();
if (i < 11)
@@ -345,12 +345,10 @@ void Display::Tags(const MPD::Song &s, void *data, Menu<MPD::Song> *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();
}
}

View File

@@ -51,7 +51,7 @@ namespace Display
void Songs(const MPD::Song &, void *, Menu<MPD::Song> *);
void Tags(const MPD::Song &, void *, Menu<MPD::Song> *);
void Tags(const MPD::MutableSong &, void *, Menu<MPD::MutableSong> *);
void Outputs(const MPD::Output &, void *, Menu<MPD::Output> *);

View File

@@ -365,24 +365,16 @@ void UpdateSongList(Menu<MPD::Song> *menu)
}
#ifdef HAVE_TAGLIB_H
std::string FindSharedDir(Menu<MPD::Song> *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;

View File

@@ -220,11 +220,20 @@ std::string Timestamp(time_t t);
void UpdateSongList(Menu<MPD::Song> *);
std::string FindSharedDir(const std::string &, const std::string &);
#ifdef HAVE_TAGLIB_H
std::string FindSharedDir(Menu<MPD::Song> *);
template <typename T> std::string FindSharedDir(Menu<T> *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);

View File

@@ -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<void(Output &&)> f)
{
if (!itsConnection)

197
src/mutable_song.cpp Normal file
View File

@@ -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<std::string()> 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;
}
}

97
src/mutable_song.h Normal file
View File

@@ -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 <map>
#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<std::string()> 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<Tag, std::string> m_tags;
};
}
#endif // _EDITABLE_SONG_H

View File

@@ -136,13 +136,10 @@ 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;
}

View File

@@ -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<struct SongImpl> pimpl;
};

View File

@@ -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;

View File

@@ -31,7 +31,7 @@ class SongInfo : public Screen<Scrollpad>
{
const char *Name;
MPD::Song::GetFunction Get;
//MPD::Song::SetFunction Set;
MPD::MutableSong::SetFunction Set;
};
virtual void SwitchTo();

42
src/string_utilities.cpp Normal file
View File

@@ -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 <cassert>
#include "string_utilities.h"
std::vector<std::string> split(const std::string &s, const std::string &delimiter)
{
if (delimiter.empty())
return { s };
std::vector<std::string> 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;
}

29
src/string_utilities.h Normal file
View File

@@ -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 <string>
#include <vector>
std::vector<std::string> split(const std::string &s, const std::string &delimiter);
#endif // _STRING_UTILITIES

View File

@@ -103,7 +103,7 @@ void TagEditor::Init()
TagTypes->AddOption("Reset");
TagTypes->AddOption("Save");
Tags = new Menu<MPD::Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, Config.titles_visibility ? "Tags" : "", Config.main_color, brNone);
Tags = new Menu<MPD::MutableSong>(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<CaseInsensitiveSorting>();
@@ -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<size_t> selected;
Tags->GetSelected(selected);
for (std::vector<size_t>::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<std::string>::apply(i) + "/" + unsignedIntTo<std::string>::apply(EditedSongs.size()));
else
(*it)->SetTrack(i);
(*it)->setTrack(unsignedIntTo<std::string>::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<size_t>::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<MPD::Song>((*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<TagLib::MPEG::File *>(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<std::string>::apply(f.tag()->track()));
s.setDate(intTo<std::string>::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<Menu<std::string> *>(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<std::string> 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";

View File

@@ -21,9 +21,7 @@
#ifndef _TAG_EDITOR_H
#define _TAG_EDITOR_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "config.h"
#ifdef HAVE_TAGLIB_H
@@ -79,13 +77,13 @@ class TagEditor : public Screen<Window>
Menu<string_pair> *Albums;
Menu<string_pair> *Dirs;
Menu<std::string> *TagTypes;
Menu<MPD::Song> *Tags;
Menu<MPD::MutableSong> *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<Window>
private:
void SetDimensions(size_t, size_t);
MPD::SongList EditedSongs;
std::vector<MPD::MutableSong *> EditedSongs;
Menu<std::string> *FParserDialog;
Menu<std::string> *FParser;
Scrollpad *FParserHelper;
@@ -103,18 +101,18 @@ class TagEditor : public Screen<Window>
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;

View File

@@ -104,48 +104,42 @@ std::basic_string<my_char_t> 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";

View File

@@ -21,9 +21,7 @@
#ifndef _TINY_TAG_EDITOR_H
#define _TINY_TAG_EDITOR_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "config.h"
#ifdef HAVE_TAGLIB_H
@@ -58,7 +56,7 @@ class TinyTagEditor : public Screen< Menu<Buffer> >
private:
bool getTags();
MPD::Song itsEdited;
MPD::MutableSong itsEdited;
static bool extendedTagsSupported(TagLib::File *);
};