fix statusbar scrolling speed with idle mode and bitrate displayed
[ncmpcpp.git] / src / tiny_tag_editor.cpp
blob66c220b0d3811eeb75e9fc0d163dd1c534a8f2b8
1 /***************************************************************************
2 * Copyright (C) 2008-2010 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include "tiny_tag_editor.h"
23 #ifdef HAVE_TAGLIB_H
25 // taglib includes
26 #include "mpegfile.h"
27 #include "vorbisfile.h"
28 #include "flacfile.h"
30 #include "browser.h"
31 #include "charset.h"
32 #include "display.h"
33 #include "global.h"
34 #include "info.h"
35 #include "playlist.h"
36 #include "search_engine.h"
37 #include "tag_editor.h"
39 using Global::MainHeight;
40 using Global::MainStartY;
41 using Global::myOldScreen;
43 TinyTagEditor *myTinyTagEditor = new TinyTagEditor;
45 void TinyTagEditor::Init()
47 w = new Menu<Buffer>(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
48 w->HighlightColor(Config.main_highlight_color);
49 w->CyclicScrolling(Config.use_cyclic_scrolling);
50 w->CenteredCursor(Config.centered_cursor);
51 w->SetItemDisplayer(Display::Generic);
52 isInitialized = 1;
55 void TinyTagEditor::Resize()
57 w->Resize(COLS, MainHeight);
58 w->MoveTo(0, MainStartY);
59 hasToBeResized = 0;
62 void TinyTagEditor::SwitchTo()
64 if (itsEdited.isStream())
66 ShowMessage("Streams cannot be edited!");
68 else if (GetTags())
70 if (hasToBeResized)
71 Resize();
72 myOldScreen = Global::myScreen;
73 Global::myScreen = this;
74 Global::RedrawHeader = 1;
76 else
78 std::string full_path;
79 if (itsEdited.isFromDB())
80 full_path += Config.mpd_music_dir;
81 full_path += itsEdited.GetFile();
83 std::string message = "Couldn't read file \"";
84 message += Shorten(TO_WSTRING(full_path), COLS-message.length()-3);
85 message += "\"!";
86 ShowMessage("%s", message.c_str());
90 std::basic_string<my_char_t> TinyTagEditor::Title()
92 return U("Tiny tag editor");
95 void TinyTagEditor::EnterPressed()
97 size_t option = w->Choice();
98 MPD::Song &s = itsEdited;
100 LockStatusbar();
101 if (option < 19) // separator after comment
103 size_t pos = option-8;
104 Statusbar() << fmtBold << Info::Tags[pos].Name << ": " << fmtBoldEnd;
105 s.SetTags(Info::Tags[pos].Set, Global::wFooter->GetString(s.GetTags(Info::Tags[pos].Get)));
106 w->at(option).Clear();
107 w->at(option) << fmtBold << Info::Tags[pos].Name << ':' << fmtBoldEnd << ' ';
108 ShowTag(w->at(option), s.GetTags(Info::Tags[pos].Get));
110 else if (option == 20)
112 Statusbar() << fmtBold << "Filename: " << fmtBoldEnd;
113 std::string filename = s.GetNewName().empty() ? s.GetName() : s.GetNewName();
114 size_t dot = filename.rfind(".");
115 std::string extension = filename.substr(dot);
116 filename = filename.substr(0, dot);
117 std::string new_name = Global::wFooter->GetString(filename);
118 s.SetNewName(new_name + extension);
119 w->at(option).Clear();
120 w->at(option) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << (s.GetNewName().empty() ? s.GetName() : s.GetNewName());
122 UnlockStatusbar();
124 if (option == 22)
126 ShowMessage("Updating tags...");
127 if (TagEditor::WriteTags(s))
129 ShowMessage("Tags updated!");
130 if (s.isFromDB())
132 Mpd.UpdateDirectory(locale_to_utf_cpy(s.GetDirectory()));
133 if (myOldScreen == mySearcher) // songs from search engine are not updated automatically
134 *mySearcher->Main()->Current().second = s;
136 else
138 if (myOldScreen == myPlaylist)
139 myPlaylist->Items->Current() = s;
140 else if (myOldScreen == myBrowser)
141 myBrowser->GetDirectory(myBrowser->CurrentDir());
144 else
145 ShowMessage("Error while writing tags!");
147 if (option > 21)
148 myOldScreen->SwitchTo();
151 void TinyTagEditor::MouseButtonPressed(MEVENT me)
153 if (w->Empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->Size())
154 return;
155 if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
157 if (!w->Goto(me.y))
158 return;
159 if (me.bstate & BUTTON3_PRESSED)
161 w->Refresh();
162 EnterPressed();
165 else
166 Screen< Menu<Buffer> >::MouseButtonPressed(me);
169 bool TinyTagEditor::SetEdited(MPD::Song *s)
171 if (!s)
172 return false;
173 itsEdited = *s;
174 return true;
177 bool TinyTagEditor::GetTags()
179 MPD::Song &s = itsEdited;
181 std::string path_to_file;
182 if (s.isFromDB())
183 path_to_file += Config.mpd_music_dir;
184 path_to_file += s.GetFile();
185 locale_to_utf(path_to_file);
187 TagLib::FileRef f(path_to_file.c_str());
188 if (f.isNull())
189 return false;
190 s.SetComment(f.tag()->comment().to8Bit(1));
192 std::string ext = s.GetFile();
193 ext = ext.substr(ext.rfind(".")+1);
194 ToLower(ext);
196 if (!isInitialized)
197 Init();
199 w->Clear();
200 w->Reset();
202 w->ResizeList(24);
204 for (size_t i = 0; i < 7; ++i)
205 w->Static(i, 1);
207 w->IntoSeparator(7);
208 w->IntoSeparator(19);
209 w->IntoSeparator(21);
211 if (!extendedTagsSupported(f.file()))
213 w->Static(10, 1);
214 for (size_t i = 15; i <= 17; ++i)
215 w->Static(i, 1);
218 w->Highlight(8);
220 w->at(0) << fmtBold << Config.color1 << "Song name: " << fmtBoldEnd << Config.color2 << s.GetName() << clEnd;
221 w->at(1) << fmtBold << Config.color1 << "Location in DB: " << fmtBoldEnd << Config.color2;
222 ShowTag(w->at(1), s.GetDirectory());
223 w->at(1) << clEnd;
224 w->at(3) << fmtBold << Config.color1 << "Length: " << fmtBoldEnd << Config.color2 << s.GetLength() << clEnd;
225 w->at(4) << fmtBold << Config.color1 << "Bitrate: " << fmtBoldEnd << Config.color2 << f.audioProperties()->bitrate() << " kbps" << clEnd;
226 w->at(5) << fmtBold << Config.color1 << "Sample rate: " << fmtBoldEnd << Config.color2 << f.audioProperties()->sampleRate() << " Hz" << clEnd;
227 w->at(6) << fmtBold << Config.color1 << "Channels: " << fmtBoldEnd << Config.color2 << (f.audioProperties()->channels() == 1 ? "Mono" : "Stereo") << clDefault;
229 unsigned pos = 8;
230 for (const Info::Metadata *m = Info::Tags; m->Name; ++m, ++pos)
232 w->at(pos) << fmtBold << m->Name << ":" << fmtBoldEnd << ' ';
233 ShowTag(w->at(pos), s.GetTags(m->Get));
236 w->at(20) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << s.GetName();
238 w->at(22) << "Save";
239 w->at(23) << "Cancel";
240 return true;
243 bool TinyTagEditor::extendedTagsSupported(TagLib::File *f)
245 return dynamic_cast<TagLib::MPEG::File *>(f)
246 || dynamic_cast<TagLib::Ogg::Vorbis::File *>(f)
247 || dynamic_cast<TagLib::FLAC::File *>(f);
250 #endif // HAVE_TAGLIB_H