move TinyTagEditor class to separate file / a bit of code cleaning

This commit is contained in:
Andrzej Rybczak
2009-08-30 06:37:53 +02:00
parent 18e611bee2
commit 0959336040
6 changed files with 456 additions and 390 deletions

View File

@@ -3,7 +3,7 @@ ncmpcpp_SOURCES = browser.cpp charset.cpp clock.cpp conv.cpp display.cpp \
help.cpp helpers.cpp info.cpp libmpdclient.c lyrics.cpp media_library.cpp \
menu.cpp misc.cpp mpdpp.cpp ncmpcpp.cpp outputs.cpp playlist.cpp \
playlist_editor.cpp scrollpad.cpp search_engine.cpp settings.cpp song.cpp status.cpp \
str_pool.c tag_editor.cpp visualizer.cpp window.cpp
str_pool.c tag_editor.cpp tiny_tag_editor.cpp visualizer.cpp window.cpp
# set the include path found by configure
INCLUDES= $(all_includes)
@@ -13,4 +13,4 @@ ncmpcpp_LDFLAGS = $(all_libraries)
noinst_HEADERS = browser.h charset.h clock.h conv.h display.h global.h help.h \
helpers.h home.h info.h lyrics.h media_library.h menu.h misc.h mpdpp.h outputs.h \
playlist_editor.h screen.h scrollpad.h search_engine.h settings.h song.h tag_editor.h \
visualizer.h window.h
tiny_tag_editor.h visualizer.h window.h

View File

@@ -49,6 +49,7 @@
#include "outputs.h"
#include "status.h"
#include "tag_editor.h"
#include "tiny_tag_editor.h"
#include "visualizer.h"
#define CHECK_PLAYLIST_FOR_FILTERING \

View File

@@ -29,285 +29,16 @@
#include "textidentificationframe.h"
#include "mpegfile.h"
#include "browser.h"
#include "charset.h"
#include "display.h"
#include "global.h"
#include "helpers.h"
#include "media_library.h"
#include "playlist.h"
#include "playlist_editor.h"
#include "search_engine.h"
#include "status.h"
using namespace Global;
using namespace MPD;
TinyTagEditor *myTinyTagEditor = new TinyTagEditor;
void TinyTagEditor::Init()
{
w = new Menu<Buffer>(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
w->HighlightColor(Config.main_highlight_color);
w->SetTimeout(ncmpcpp_window_timeout);
w->CyclicScrolling(Config.use_cyclic_scrolling);
w->SetItemDisplayer(Display::Generic);
isInitialized = 1;
}
void TinyTagEditor::Resize()
{
w->Resize(COLS, MainHeight);
w->MoveTo(0, MainStartY);
hasToBeResized = 0;
}
void TinyTagEditor::SwitchTo()
{
if (itsEdited.isStream())
{
ShowMessage("Cannot edit streams!");
}
else if (GetTags())
{
if (hasToBeResized)
Resize();
myOldScreen = myScreen;
myScreen = this;
RedrawHeader = 1;
}
else
{
std::string message = "Cannot read file '";
if (itsEdited.isFromDB())
message += Config.mpd_music_dir;
message += itsEdited.GetFile();
message += "'!";
ShowMessage("%s", message.c_str());
}
}
std::basic_string<my_char_t> TinyTagEditor::Title()
{
return U("Tiny tag editor");
}
void TinyTagEditor::EnterPressed()
{
size_t option = w->Choice();
LockStatusbar();
if (option >= 8 && option <= 20)
w->at(option).Clear();
Song &s = itsEdited;
switch (option-7)
{
case 1:
{
Statusbar() << fmtBold << "Title: " << fmtBoldEnd;
s.SetTitle(wFooter->GetString(s.GetTitle()));
w->at(option) << fmtBold << "Title:" << fmtBoldEnd << ' ' << ShowTag(s.GetTitle());
break;
}
case 2:
{
Statusbar() << fmtBold << "Artist: " << fmtBoldEnd;
s.SetArtist(wFooter->GetString(s.GetArtist()));
w->at(option) << fmtBold << "Artist:" << fmtBoldEnd << ' ' << ShowTag(s.GetArtist());
break;
}
case 3:
{
Statusbar() << fmtBold << "Album: " << fmtBoldEnd;
s.SetAlbum(wFooter->GetString(s.GetAlbum()));
w->at(option) << fmtBold << "Album:" << fmtBoldEnd << ' ' << ShowTag(s.GetAlbum());
break;
}
case 4:
{
Statusbar() << fmtBold << "Year: " << fmtBoldEnd;
s.SetDate(wFooter->GetString(s.GetDate()));
w->at(option) << fmtBold << "Year:" << fmtBoldEnd << ' ' << ShowTag(s.GetDate());
break;
}
case 5:
{
Statusbar() << fmtBold << "Track: " << fmtBoldEnd;
s.SetTrack(wFooter->GetString(s.GetTrack()));
w->at(option) << fmtBold << "Track:" << fmtBoldEnd << ' ' << ShowTag(s.GetTrack());
break;
}
case 6:
{
Statusbar() << fmtBold << "Genre: " << fmtBoldEnd;
s.SetGenre(wFooter->GetString(s.GetGenre()));
w->at(option) << fmtBold << "Genre:" << fmtBoldEnd << ' ' << ShowTag(s.GetGenre());
break;
}
case 7:
{
Statusbar() << fmtBold << "Composer: " << fmtBoldEnd;
s.SetComposer(wFooter->GetString(s.GetComposer()));
w->at(option) << fmtBold << "Composer:" << fmtBoldEnd << ' ' << ShowTag(s.GetComposer());
break;
}
case 8:
{
Statusbar() << fmtBold << "Performer: " << fmtBoldEnd;
s.SetPerformer(wFooter->GetString(s.GetPerformer()));
w->at(option) << fmtBold << "Performer:" << fmtBoldEnd << ' ' << ShowTag(s.GetPerformer());
break;
}
case 9:
{
Statusbar() << fmtBold << "Disc: " << fmtBoldEnd;
s.SetDisc(wFooter->GetString(s.GetDisc()));
w->at(option) << fmtBold << "Disc:" << fmtBoldEnd << ' ' << ShowTag(s.GetDisc());
break;
}
case 10:
{
Statusbar() << fmtBold << "Comment: " << fmtBoldEnd;
s.SetComment(wFooter->GetString(s.GetComment()));
w->at(option) << fmtBold << "Comment:" << fmtBoldEnd << ' ' << ShowTag(s.GetComment());
break;
}
case 12:
{
Statusbar() << fmtBold << "Filename: " << fmtBoldEnd;
std::string filename = s.GetNewName().empty() ? s.GetName() : s.GetNewName();
size_t dot = filename.rfind(".");
std::string extension = filename.substr(dot);
filename = filename.substr(0, dot);
std::string new_name = wFooter->GetString(filename);
s.SetNewName(new_name + extension);
w->at(option) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << (s.GetNewName().empty() ? s.GetName() : s.GetNewName());
break;
}
case 14:
{
ShowMessage("Updating tags...");
if (TagEditor::WriteTags(s))
{
ShowMessage("Tags updated!");
if (s.isFromDB())
{
Mpd.UpdateDirectory(locale_to_utf_cpy(s.GetDirectory()));
if (myOldScreen == mySearcher)
*mySearcher->Main()->Current().second = s;
}
else
{
if (myOldScreen == myPlaylist)
myPlaylist->Items->Current() = s;
else if (myOldScreen == myBrowser)
*myBrowser->Main()->Current().song = s;
}
}
else
ShowMessage("Error writing tags!");
}
case 15:
{
myOldScreen->SwitchTo();
break;
}
}
UnlockStatusbar();
}
void TinyTagEditor::MouseButtonPressed(MEVENT me)
{
if (w->Empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->Size())
return;
if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
{
if (!w->Goto(me.y))
return;
if (me.bstate & BUTTON3_PRESSED)
{
w->Refresh();
EnterPressed();
}
}
else
Screen< Menu<Buffer> >::MouseButtonPressed(me);
}
bool TinyTagEditor::SetEdited(MPD::Song *s)
{
if (!s)
return false;
itsEdited = *s;
return true;
}
bool TinyTagEditor::GetTags()
{
Song &s = itsEdited;
std::string path_to_file;
if (s.isFromDB())
path_to_file += Config.mpd_music_dir;
path_to_file += s.GetFile();
locale_to_utf(path_to_file);
TagLib::FileRef f(path_to_file.c_str());
if (f.isNull())
return false;
s.SetComment(f.tag()->comment().to8Bit(1));
std::string ext = s.GetFile();
ext = ext.substr(ext.rfind(".")+1);
ToLower(ext);
if (!isInitialized)
Init();
w->Clear();
w->Reset();
w->ResizeList(23);
for (size_t i = 0; i < 7; ++i)
w->Static(i, 1);
w->IntoSeparator(7);
w->IntoSeparator(18);
w->IntoSeparator(20);
if (ext != "mp3")
for (size_t i = 14; i <= 16; ++i)
w->Static(i, 1);
w->Highlight(8);
w->at(0) << fmtBold << Config.color1 << "Song name: " << fmtBoldEnd << Config.color2 << s.GetName() << clEnd;
w->at(1) << fmtBold << Config.color1 << "Location in DB: " << fmtBoldEnd << Config.color2 << ShowTag(s.GetDirectory()) << clEnd;
w->at(3) << fmtBold << Config.color1 << "Length: " << fmtBoldEnd << Config.color2 << s.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;
w->at(8) << fmtBold << "Title:" << fmtBoldEnd << ' ' << ShowTag(s.GetTitle());
w->at(9) << fmtBold << "Artist:" << fmtBoldEnd << ' ' << ShowTag(s.GetArtist());
w->at(10) << fmtBold << "Album:" << fmtBoldEnd << ' ' << ShowTag(s.GetAlbum());
w->at(11) << fmtBold << "Year:" << fmtBoldEnd << ' ' << ShowTag(s.GetDate());
w->at(12) << fmtBold << "Track:" << fmtBoldEnd << ' ' << ShowTag(s.GetTrack());
w->at(13) << fmtBold << "Genre:" << fmtBoldEnd << ' ' << ShowTag(s.GetGenre());
w->at(14) << fmtBold << "Composer:" << fmtBoldEnd << ' ' << ShowTag(s.GetComposer());
w->at(15) << fmtBold << "Performer:" << fmtBoldEnd << ' ' << ShowTag(s.GetPerformer());
w->at(16) << fmtBold << "Disc:" << fmtBoldEnd << ' ' << ShowTag(s.GetDisc());
w->at(17) << fmtBold << "Comment:" << fmtBoldEnd << ' ' << ShowTag(s.GetComment());
w->at(19) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << s.GetName();
w->at(21) << "Save";
w->at(22) << "Cancel";
return true;
}
using Global::MainHeight;
using Global::MainStartY;
using Global::myOldScreen;
using Global::myScreen;
using Global::wFooter;
TagEditor *myTagEditor = new TagEditor;
@@ -349,7 +80,7 @@ void TagEditor::Init()
TagTypes->CyclicScrolling(Config.use_cyclic_scrolling);
TagTypes->SetItemDisplayer(Display::Generic);
Tags = new Menu<Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, "Tags", Config.main_color, brNone);
Tags = new Menu<MPD::Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, "Tags", Config.main_color, brNone);
Tags->HighlightColor(Config.main_highlight_color);
Tags->SetTimeout(ncmpcpp_window_timeout);
Tags->CyclicScrolling(Config.use_cyclic_scrolling);
@@ -401,7 +132,7 @@ void TagEditor::SwitchTo()
Resize();
myScreen = this;
RedrawHeader = 1;
Global::RedrawHeader = 1;
Refresh();
if (TagTypes->Empty())
@@ -444,16 +175,15 @@ void TagEditor::Update()
{
LeftColumn->Window::Clear();
Tags->Clear();
TagList list;
MPD::TagList list;
if (Config.albums_in_tag_editor)
{
*Albums << XY(0, 0) << "Fetching albums...";
Albums->Window::Refresh();
Mpd.GetAlbums("", list);
for (TagList::const_iterator it = list.begin(); it != list.end(); ++it)
for (MPD::TagList::const_iterator it = list.begin(); it != list.end(); ++it)
{
SongList l;
MPD::SongList l;
Mpd.StartSearch(1);
Mpd.AddSearch(MPD_TAG_ITEM_ALBUM, *it);
Mpd.CommitSearch(l);
@@ -462,7 +192,7 @@ void TagEditor::Update()
l[0]->Localize();
Albums->AddOption(std::make_pair(l[0]->toString(Config.tag_editor_album_format), *it));
}
FreeSongList(l);
MPD::FreeSongList(l);
}
Albums->Sort<CaseInsensitiveSorting>();
}
@@ -481,7 +211,7 @@ void TagEditor::Update()
{
Dirs->AddOption(std::make_pair(".", "/"));
}
for (TagList::const_iterator it = list.begin(); it != list.end(); ++it)
for (MPD::TagList::const_iterator it = list.begin(); it != list.end(); ++it)
{
size_t slash = it->rfind("/");
std::string to_display = slash != std::string::npos ? it->substr(slash+1) : *it;
@@ -500,14 +230,14 @@ void TagEditor::Update()
if (Tags->Empty())
{
Tags->Reset();
SongList list;
MPD::SongList list;
if (Config.albums_in_tag_editor)
{
Mpd.StartSearch(1);
Mpd.AddSearch(MPD_TAG_ITEM_ALBUM, Albums->Current().second);
Mpd.CommitSearch(list);
sort(list.begin(), list.end(), CaseInsensitiveSorting());
for (SongList::iterator it = list.begin(); it != list.end(); ++it)
for (MPD::SongList::iterator it = list.begin(); it != list.end(); ++it)
{
(*it)->Localize();
Tags->AddOption(**it);
@@ -517,13 +247,13 @@ void TagEditor::Update()
{
Mpd.GetSongs(Dirs->Current().second, list);
sort(list.begin(), list.end(), CaseInsensitiveSorting());
for (SongList::const_iterator it = list.begin(); it != list.end(); ++it)
for (MPD::SongList::const_iterator it = list.begin(); it != list.end(); ++it)
{
(*it)->Localize();
Tags->AddOption(**it);
}
}
FreeSongList(list);
MPD::FreeSongList(list);
Tags->Window::Clear();
Tags->Refresh();
}
@@ -540,7 +270,7 @@ void TagEditor::EnterPressed()
{
if (w == Dirs)
{
TagList test;
MPD::TagList test;
Mpd.GetDirectories(LeftColumn->Current().second, test);
if (!test.empty())
{
@@ -558,43 +288,43 @@ void TagEditor::EnterPressed()
return;
// if there are selected songs, perform operations only on them
SongList list;
MPD::SongList list;
if (Tags->hasSelected())
{
std::vector<size_t> selected;
Tags->GetSelected(selected);
for (std::vector<size_t>::const_iterator it = selected.begin(); it != selected.end(); ++it)
list.push_back(&Tags->at(*it));
list.push_back(&(*Tags)[*it]);
}
else
for (size_t i = 0; i < Tags->Size(); ++i)
list.push_back(&Tags->at(i));
list.push_back(&(*Tags)[i]);
Song::GetFunction get = 0;
Song::SetFunction set = 0;
MPD::Song::GetFunction get = 0;
MPD::Song::SetFunction set = 0;
size_t id = TagTypes->RealChoice();
switch (id)
{
case 0:
get = &Song::GetTitle;
set = &Song::SetTitle;
get = &MPD::Song::GetTitle;
set = &MPD::Song::SetTitle;
break;
case 1:
get = &Song::GetArtist;
set = &Song::SetArtist;
get = &MPD::Song::GetArtist;
set = &MPD::Song::SetArtist;
break;
case 2:
get = &Song::GetAlbum;
set = &Song::SetAlbum;
get = &MPD::Song::GetAlbum;
set = &MPD::Song::SetAlbum;
break;
case 3:
get = &Song::GetDate;
set = &Song::SetDate;
get = &MPD::Song::GetDate;
set = &MPD::Song::SetDate;
break;
case 4:
get = &Song::GetTrack;
set = &Song::SetTrack;
get = &MPD::Song::GetTrack;
set = &MPD::Song::SetTrack;
if (w == TagTypes)
{
LockStatusbar();
@@ -609,8 +339,8 @@ void TagEditor::EnterPressed()
while (in != 'y' && in != 'n');
if (in == 'y')
{
int i = 1;
for (SongList::iterator it = list.begin(); it != list.end(); ++it, ++i)
MPD::SongList::iterator it = list.begin();
for (unsigned i = 1; i <= list.size(); ++i, ++it)
(*it)->SetTrack(i);
ShowMessage("Tracks numbered!");
}
@@ -621,24 +351,24 @@ void TagEditor::EnterPressed()
}
break;
case 5:
get = &Song::GetGenre;
set = &Song::SetGenre;
get = &MPD::Song::GetGenre;
set = &MPD::Song::SetGenre;
break;
case 6:
get = &Song::GetComposer;
set = &Song::SetComposer;
get = &MPD::Song::GetComposer;
set = &MPD::Song::SetComposer;
break;
case 7:
get = &Song::GetPerformer;
set = &Song::SetPerformer;
get = &MPD::Song::GetPerformer;
set = &MPD::Song::SetPerformer;
break;
case 8:
get = &Song::GetDisc;
set = &Song::SetDisc;
get = &MPD::Song::GetDisc;
set = &MPD::Song::SetDisc;
break;
case 9:
get = &Song::GetComment;
set = &Song::SetComment;
get = &MPD::Song::GetComment;
set = &MPD::Song::SetComment;
break;
case 10:
{
@@ -649,7 +379,7 @@ void TagEditor::EnterPressed()
}
else if (w == Tags)
{
Song &s = Tags->Current();
MPD::Song &s = Tags->Current();
std::string old_name = s.GetNewName().empty() ? s.GetName() : s.GetNewName();
size_t last_dot = old_name.rfind(".");
std::string extension = old_name.substr(last_dot);
@@ -674,7 +404,7 @@ void TagEditor::EnterPressed()
{
bool success = 1;
ShowMessage("Writing changes...");
for (SongList::iterator it = list.begin(); it != list.end(); ++it)
for (MPD::SongList::iterator it = list.begin(); it != list.end(); ++it)
{
ShowMessage("Writing tags in \"%s\"...", (*it)->GetName().c_str());
if (!WriteTags(**it))
@@ -701,7 +431,7 @@ void TagEditor::EnterPressed()
case 13: // capitalize first letters
{
ShowMessage("Processing...");
for (SongList::iterator it = list.begin(); it != list.end(); ++it)
for (MPD::SongList::iterator it = list.begin(); it != list.end(); ++it)
CapitalizeFirstLetters(**it);
ShowMessage("Done!");
break;
@@ -709,7 +439,7 @@ void TagEditor::EnterPressed()
case 14: // lower all letters
{
ShowMessage("Processing...");
for (SongList::iterator it = list.begin(); it != list.end(); ++it)
for (MPD::SongList::iterator it = list.begin(); it != list.end(); ++it)
LowerAllLetters(**it);
ShowMessage("Done!");
break;
@@ -718,16 +448,16 @@ void TagEditor::EnterPressed()
break;
}
if (w == TagTypes && id != 0 && id != 4 && set != NULL)
if (w == TagTypes && id != 0 && id != 4 && set)
{
LockStatusbar();
Statusbar() << fmtBold << TagTypes->Current() << fmtBoldEnd << ": ";
std::string new_tag = wFooter->GetString((Tags->Current().*get)());
UnlockStatusbar();
for (SongList::iterator it = list.begin(); it != list.end(); ++it)
for (MPD::SongList::iterator it = list.begin(); it != list.end(); ++it)
(**it.*set)(new_tag);
}
else if (w == Tags && set != NULL)
else if (w == Tags && set)
{
LockStatusbar();
Statusbar() << fmtBold << TagTypes->Current() << fmtBoldEnd << ": ";
@@ -823,9 +553,7 @@ void TagEditor::GetSelectedSongs(MPD::SongList &v)
std::vector<size_t> selected;
Tags->GetSelected(selected);
for (std::vector<size_t>::const_iterator it = selected.begin(); it != selected.end(); ++it)
{
v.push_back(new MPD::Song(Tags->at(*it)));
}
}
void TagEditor::ApplyFilter(const std::string &s)
@@ -861,7 +589,7 @@ void TagEditor::NextColumn()
{
TagTypes->HighlightColor(Config.main_highlight_color);
w->Refresh();
w = myTagEditor->Tags;
w = Tags;
Tags->HighlightColor(Config.active_column_color);
}
}
@@ -932,7 +660,7 @@ namespace
}
}
bool TagEditor::WriteTags(Song &s)
bool TagEditor::WriteTags(MPD::Song &s)
{
std::string path_to_file;
bool file_is_from_db = s.isFromDB();
@@ -975,7 +703,7 @@ bool TagEditor::WriteTags(Song &s)
WriteID3v2("TDRC", tag, ToWString(s.GetDate())); // date
WriteID3v2("TRCK", tag, ToWString(s.GetTrack())); // track
WriteID3v2("TCON", tag, ToWString(s.GetGenre())); // genre
WriteID3v2("TPOS", tag, ToWString(s.GetDisc())); // disc
WriteID3v2("TPOS", tag, ToWString(s.GetDisc())); // disc
GetTagList(list, s.GetComposer());
WriteID3v2("TCOM", tag, list); // composer
@@ -1036,7 +764,7 @@ std::string TagEditor::CapitalizeFirstLetters(const std::string &s)
return result;
}
void TagEditor::CapitalizeFirstLetters(Song &s)
void TagEditor::CapitalizeFirstLetters(MPD::Song &s)
{
s.SetTitle(CapitalizeFirstLetters(s.GetTitle()));
s.SetArtist(CapitalizeFirstLetters(s.GetArtist()));
@@ -1048,7 +776,7 @@ void TagEditor::CapitalizeFirstLetters(Song &s)
s.SetComment(CapitalizeFirstLetters(s.GetComment()));
}
void TagEditor::LowerAllLetters(Song &s)
void TagEditor::LowerAllLetters(MPD::Song &s)
{
std::string conv = s.GetTitle();
ToLower(conv);
@@ -1131,10 +859,7 @@ std::string TagEditor::TagToString(const MPD::Song &s, void *data)
result = s.GetComment();
break;
case 11:
if (s.GetNewName().empty())
result = s.GetName();
else
result = s.GetName() + " -> " + s.GetNewName();
result = s.GetNewName().empty() ? s.GetName() : s.GetName() + " -> " + s.GetNewName();
break;
default:
break;
@@ -1151,10 +876,8 @@ void TagEditor::GetPatternList()
{
std::string line;
while (getline(input, line))
{
if (!line.empty())
Patterns.push_back(line);
}
input.close();
}
}
@@ -1171,43 +894,43 @@ void TagEditor::SavePatternList()
}
}
Song::SetFunction TagEditor::IntoSetFunction(char c)
MPD::Song::SetFunction TagEditor::IntoSetFunction(char c)
{
switch (c)
{
case 'a':
return &Song::SetArtist;
return &MPD::Song::SetArtist;
case 't':
return &Song::SetTitle;
return &MPD::Song::SetTitle;
case 'b':
return &Song::SetAlbum;
return &MPD::Song::SetAlbum;
case 'y':
return &Song::SetDate;
return &MPD::Song::SetDate;
case 'n':
return &Song::SetTrack;
return &MPD::Song::SetTrack;
case 'g':
return &Song::SetGenre;
return &MPD::Song::SetGenre;
case 'c':
return &Song::SetComposer;
return &MPD::Song::SetComposer;
case 'p':
return &Song::SetPerformer;
return &MPD::Song::SetPerformer;
case 'd':
return &Song::SetDisc;
return &MPD::Song::SetDisc;
case 'C':
return &Song::SetComment;
return &MPD::Song::SetComment;
default:
return NULL;
return 0;
}
}
std::string TagEditor::GenerateFilename(const Song &s, const std::string &pattern)
std::string TagEditor::GenerateFilename(const MPD::Song &s, const std::string &pattern)
{
std::string result = s.toString(pattern);
EscapeUnallowedChars(result);
return result;
}
std::string TagEditor::ParseFilename(Song &s, std::string mask, bool preview)
std::string TagEditor::ParseFilename(MPD::Song &s, std::string mask, bool preview)
{
std::ostringstream result;
std::vector<std::string> separators;
@@ -1224,10 +947,10 @@ std::string TagEditor::ParseFilename(Song &s, std::string mask, bool preview)
if (!mask.empty())
separators.push_back(mask.substr(0, i));
}
int i = 0;
size_t i = 0;
for (std::vector<std::string>::const_iterator it = separators.begin(); it != separators.end(); ++it, ++i)
{
int j = file.find(*it);
size_t j = file.find(*it);
tags.at(i).second = file.substr(0, j);
file = file.substr(j+it->length());
}
@@ -1247,7 +970,7 @@ std::string TagEditor::ParseFilename(Song &s, std::string mask, bool preview)
if (!preview)
{
Song::SetFunction set = IntoSetFunction(it->first);
MPD::Song::SetFunction set = IntoSetFunction(it->first);
if (set)
(s.*set)(it->second);
}
@@ -1257,7 +980,7 @@ std::string TagEditor::ParseFilename(Song &s, std::string mask, bool preview)
return result.str();
}
void TagEditor::DealWithFilenames(SongList &v)
void TagEditor::DealWithFilenames(MPD::SongList &v)
{
size_t width = 30;
size_t height = 6;
@@ -1323,7 +1046,7 @@ void TagEditor::DealWithFilenames(SongList &v)
*Legend << "%d - disc\n";
*Legend << "%C - comment\n\n";
*Legend << fmtBold << "Files:\n" << fmtBoldEnd;
for (SongList::const_iterator it = v.begin(); it != v.end(); ++it)
for (MPD::SongList::const_iterator it = v.begin(); it != v.end(); ++it)
*Legend << Config.color2 << " * " << clEnd << (*it)->GetName() << "\n";
Legend->Flush();
@@ -1403,9 +1126,9 @@ void TagEditor::DealWithFilenames(SongList &v)
bool success = 1;
ShowMessage("Parsing...");
Preview->Clear();
for (SongList::iterator it = v.begin(); it != v.end(); ++it)
for (MPD::SongList::iterator it = v.begin(); it != v.end(); ++it)
{
Song &s = **it;
MPD::Song &s = **it;
if (!choice)
{
if (preview)

View File

@@ -18,48 +18,21 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "ncmpcpp.h"
#ifdef HAVE_TAGLIB_H
#ifndef _TAG_EDITOR_H
#define _TAG_EDITOR_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_TAGLIB_H
// taglib headers
#include "fileref.h"
#include "tag.h"
#include "mpdpp.h"
#include "screen.h"
#include "settings.h"
class TinyTagEditor : public Screen< Menu<Buffer> >
{
public:
virtual void Resize();
virtual void SwitchTo();
virtual std::basic_string<my_char_t> Title();
virtual void EnterPressed();
virtual void SpacePressed() { }
virtual void MouseButtonPressed(MEVENT);
virtual bool allowsSelection() { return false; }
virtual List *GetList() { return 0; }
bool SetEdited(MPD::Song *);
protected:
virtual void Init();
private:
bool GetTags();
MPD::Song itsEdited;
};
extern TinyTagEditor *myTinyTagEditor;
class TagEditor : public Screen<Window>
{

306
src/tiny_tag_editor.cpp Normal file
View File

@@ -0,0 +1,306 @@
/***************************************************************************
* Copyright (C) 2008-2009 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 "tiny_tag_editor.h"
#ifdef HAVE_TAGLIB_H
#include "browser.h"
#include "charset.h"
#include "display.h"
#include "global.h"
#include "playlist.h"
#include "search_engine.h"
#include "tag_editor.h"
using Global::MainHeight;
using Global::MainStartY;
using Global::myOldScreen;
using Global::myScreen;
using Global::wFooter;
TinyTagEditor *myTinyTagEditor = new TinyTagEditor;
void TinyTagEditor::Init()
{
w = new Menu<Buffer>(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
w->HighlightColor(Config.main_highlight_color);
w->SetTimeout(ncmpcpp_window_timeout);
w->CyclicScrolling(Config.use_cyclic_scrolling);
w->SetItemDisplayer(Display::Generic);
isInitialized = 1;
}
void TinyTagEditor::Resize()
{
w->Resize(COLS, MainHeight);
w->MoveTo(0, MainStartY);
hasToBeResized = 0;
}
void TinyTagEditor::SwitchTo()
{
if (itsEdited.isStream())
{
ShowMessage("Cannot edit streams!");
}
else if (GetTags())
{
if (hasToBeResized)
Resize();
myOldScreen = myScreen;
myScreen = this;
Global::RedrawHeader = 1;
}
else
{
std::string message = "Cannot read file '";
if (itsEdited.isFromDB())
message += Config.mpd_music_dir;
message += itsEdited.GetFile();
message += "'!";
ShowMessage("%s", message.c_str());
}
}
std::basic_string<my_char_t> TinyTagEditor::Title()
{
return U("Tiny tag editor");
}
void TinyTagEditor::EnterPressed()
{
size_t option = w->Choice();
LockStatusbar();
if (option >= 8 && option <= 20)
w->at(option).Clear();
MPD::Song &s = itsEdited;
switch (option-7)
{
case 1:
{
Statusbar() << fmtBold << "Title: " << fmtBoldEnd;
s.SetTitle(wFooter->GetString(s.GetTitle()));
w->at(option) << fmtBold << "Title:" << fmtBoldEnd << ' ' << ShowTag(s.GetTitle());
break;
}
case 2:
{
Statusbar() << fmtBold << "Artist: " << fmtBoldEnd;
s.SetArtist(wFooter->GetString(s.GetArtist()));
w->at(option) << fmtBold << "Artist:" << fmtBoldEnd << ' ' << ShowTag(s.GetArtist());
break;
}
case 3:
{
Statusbar() << fmtBold << "Album: " << fmtBoldEnd;
s.SetAlbum(wFooter->GetString(s.GetAlbum()));
w->at(option) << fmtBold << "Album:" << fmtBoldEnd << ' ' << ShowTag(s.GetAlbum());
break;
}
case 4:
{
Statusbar() << fmtBold << "Year: " << fmtBoldEnd;
s.SetDate(wFooter->GetString(s.GetDate()));
w->at(option) << fmtBold << "Year:" << fmtBoldEnd << ' ' << ShowTag(s.GetDate());
break;
}
case 5:
{
Statusbar() << fmtBold << "Track: " << fmtBoldEnd;
s.SetTrack(wFooter->GetString(s.GetTrack()));
w->at(option) << fmtBold << "Track:" << fmtBoldEnd << ' ' << ShowTag(s.GetTrack());
break;
}
case 6:
{
Statusbar() << fmtBold << "Genre: " << fmtBoldEnd;
s.SetGenre(wFooter->GetString(s.GetGenre()));
w->at(option) << fmtBold << "Genre:" << fmtBoldEnd << ' ' << ShowTag(s.GetGenre());
break;
}
case 7:
{
Statusbar() << fmtBold << "Composer: " << fmtBoldEnd;
s.SetComposer(wFooter->GetString(s.GetComposer()));
w->at(option) << fmtBold << "Composer:" << fmtBoldEnd << ' ' << ShowTag(s.GetComposer());
break;
}
case 8:
{
Statusbar() << fmtBold << "Performer: " << fmtBoldEnd;
s.SetPerformer(wFooter->GetString(s.GetPerformer()));
w->at(option) << fmtBold << "Performer:" << fmtBoldEnd << ' ' << ShowTag(s.GetPerformer());
break;
}
case 9:
{
Statusbar() << fmtBold << "Disc: " << fmtBoldEnd;
s.SetDisc(wFooter->GetString(s.GetDisc()));
w->at(option) << fmtBold << "Disc:" << fmtBoldEnd << ' ' << ShowTag(s.GetDisc());
break;
}
case 10:
{
Statusbar() << fmtBold << "Comment: " << fmtBoldEnd;
s.SetComment(wFooter->GetString(s.GetComment()));
w->at(option) << fmtBold << "Comment:" << fmtBoldEnd << ' ' << ShowTag(s.GetComment());
break;
}
case 12:
{
Statusbar() << fmtBold << "Filename: " << fmtBoldEnd;
std::string filename = s.GetNewName().empty() ? s.GetName() : s.GetNewName();
size_t dot = filename.rfind(".");
std::string extension = filename.substr(dot);
filename = filename.substr(0, dot);
std::string new_name = wFooter->GetString(filename);
s.SetNewName(new_name + extension);
w->at(option) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << (s.GetNewName().empty() ? s.GetName() : s.GetNewName());
break;
}
case 14:
{
ShowMessage("Updating tags...");
if (TagEditor::WriteTags(s))
{
ShowMessage("Tags updated!");
if (s.isFromDB())
{
Mpd.UpdateDirectory(locale_to_utf_cpy(s.GetDirectory()));
if (myOldScreen == mySearcher) // songs from search engine are not updated automatically
*mySearcher->Main()->Current().second = s;
}
else
{
if (myOldScreen == myPlaylist)
myPlaylist->Items->Current() = s;
else if (myOldScreen == myBrowser)
*myBrowser->Main()->Current().song = s;
}
}
else
ShowMessage("Error writing tags!");
}
case 15:
{
myOldScreen->SwitchTo();
break;
}
}
UnlockStatusbar();
}
void TinyTagEditor::MouseButtonPressed(MEVENT me)
{
if (w->Empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->Size())
return;
if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
{
if (!w->Goto(me.y))
return;
if (me.bstate & BUTTON3_PRESSED)
{
w->Refresh();
EnterPressed();
}
}
else
Screen< Menu<Buffer> >::MouseButtonPressed(me);
}
bool TinyTagEditor::SetEdited(MPD::Song *s)
{
if (!s)
return false;
itsEdited = *s;
return true;
}
bool TinyTagEditor::GetTags()
{
MPD::Song &s = itsEdited;
std::string path_to_file;
if (s.isFromDB())
path_to_file += Config.mpd_music_dir;
path_to_file += s.GetFile();
locale_to_utf(path_to_file);
TagLib::FileRef f(path_to_file.c_str());
if (f.isNull())
return false;
s.SetComment(f.tag()->comment().to8Bit(1));
std::string ext = s.GetFile();
ext = ext.substr(ext.rfind(".")+1);
ToLower(ext);
if (!isInitialized)
Init();
w->Clear();
w->Reset();
w->ResizeList(23);
for (size_t i = 0; i < 7; ++i)
w->Static(i, 1);
w->IntoSeparator(7);
w->IntoSeparator(18);
w->IntoSeparator(20);
if (ext != "mp3")
for (size_t i = 14; i <= 16; ++i)
w->Static(i, 1);
w->Highlight(8);
w->at(0) << fmtBold << Config.color1 << "Song name: " << fmtBoldEnd << Config.color2 << s.GetName() << clEnd;
w->at(1) << fmtBold << Config.color1 << "Location in DB: " << fmtBoldEnd << Config.color2 << ShowTag(s.GetDirectory()) << clEnd;
w->at(3) << fmtBold << Config.color1 << "Length: " << fmtBoldEnd << Config.color2 << s.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;
w->at(8) << fmtBold << "Title:" << fmtBoldEnd << ' ' << ShowTag(s.GetTitle());
w->at(9) << fmtBold << "Artist:" << fmtBoldEnd << ' ' << ShowTag(s.GetArtist());
w->at(10) << fmtBold << "Album:" << fmtBoldEnd << ' ' << ShowTag(s.GetAlbum());
w->at(11) << fmtBold << "Year:" << fmtBoldEnd << ' ' << ShowTag(s.GetDate());
w->at(12) << fmtBold << "Track:" << fmtBoldEnd << ' ' << ShowTag(s.GetTrack());
w->at(13) << fmtBold << "Genre:" << fmtBoldEnd << ' ' << ShowTag(s.GetGenre());
w->at(14) << fmtBold << "Composer:" << fmtBoldEnd << ' ' << ShowTag(s.GetComposer());
w->at(15) << fmtBold << "Performer:" << fmtBoldEnd << ' ' << ShowTag(s.GetPerformer());
w->at(16) << fmtBold << "Disc:" << fmtBoldEnd << ' ' << ShowTag(s.GetDisc());
w->at(17) << fmtBold << "Comment:" << fmtBoldEnd << ' ' << ShowTag(s.GetComment());
w->at(19) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << s.GetName();
w->at(21) << "Save";
w->at(22) << "Cancel";
return true;
}
#endif // HAVE_TAGLIB_H

63
src/tiny_tag_editor.h Normal file
View File

@@ -0,0 +1,63 @@
/***************************************************************************
* Copyright (C) 2008-2009 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 _TINY_TAG_EDITOR_H
#define _TINY_TAG_EDITOR_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_TAGLIB_H
#include "screen.h"
class TinyTagEditor : public Screen< Menu<Buffer> >
{
public:
virtual void Resize();
virtual void SwitchTo();
virtual std::basic_string<my_char_t> Title();
virtual void EnterPressed();
virtual void SpacePressed() { }
virtual void MouseButtonPressed(MEVENT);
virtual bool allowsSelection() { return false; }
virtual List *GetList() { return 0; }
bool SetEdited(MPD::Song *);
protected:
virtual void Init();
private:
bool GetTags();
MPD::Song itsEdited;
};
extern TinyTagEditor *myTinyTagEditor;
#endif // HAVE_TAGLIB_H
#endif