add find forward/backward option + some optimizations and code clean-ups

This commit is contained in:
unknown
2008-08-12 06:02:18 +02:00
parent 4c7331999a
commit 2b4518c157
7 changed files with 257 additions and 135 deletions

View File

@@ -35,9 +35,7 @@ extern Menu *mSearcher;
extern Window *wFooter; extern Window *wFooter;
extern vector<Song *> vPlaylist; extern vector<Song *> vPlaylist;
extern vector<MpdDataType> vFileType; extern vector<BrowsedItem> vBrowser;
extern vector<string> vNameList;
extern vector<long long> vHashList;
extern CurrScreen current_screen; extern CurrScreen current_screen;
@@ -511,16 +509,14 @@ void GetDirectory(string dir)
if (browsed_dir != dir) if (browsed_dir != dir)
mBrowser->Reset(); mBrowser->Reset();
browsed_dir = dir; browsed_dir = dir;
vFileType.clear(); vBrowser.clear();
vNameList.clear();
vHashList.clear();
mBrowser->Clear(0); mBrowser->Clear(0);
if (dir != "/") if (dir != "/")
{ {
mBrowser->AddOption("[..]"); mBrowser->AddOption("[..]");
vFileType.push_back(MPD_DATA_TYPE_DIRECTORY); BrowsedItem parent;
vNameList.push_back(""); parent.type = MPD_DATA_TYPE_DIRECTORY;
vHashList.push_back(0); vBrowser.push_back(parent);
} }
browser = mpd_database_get_directory(conn, (char *)dir.c_str()); browser = mpd_database_get_directory(conn, (char *)dir.c_str());
FOR_EACH_MPD_DATA(browser) FOR_EACH_MPD_DATA(browser)
@@ -529,33 +525,35 @@ void GetDirectory(string dir)
{ {
case MPD_DATA_TYPE_PLAYLIST: case MPD_DATA_TYPE_PLAYLIST:
{ {
vFileType.push_back(MPD_DATA_TYPE_PLAYLIST); BrowsedItem playlist;
vNameList.push_back(browser->playlist); playlist.type = MPD_DATA_TYPE_PLAYLIST;
vHashList.push_back(0); playlist.name = browser->playlist;
vBrowser.push_back(playlist);
mBrowser->AddOption("[red](playlist)[/red] " + string(browser->playlist)); mBrowser->AddOption("[red](playlist)[/red] " + string(browser->playlist));
break; break;
} }
case MPD_DATA_TYPE_DIRECTORY: case MPD_DATA_TYPE_DIRECTORY:
{ {
string subdir = browser->directory; string subdir = browser->directory;
vFileType.push_back(MPD_DATA_TYPE_DIRECTORY); BrowsedItem directory;
vHashList.push_back(0); directory.type = MPD_DATA_TYPE_DIRECTORY;
if (dir == "/") if (dir == "/")
vNameList.push_back(subdir.substr(browsed_dir.size()-1,subdir.size()-browsed_dir.size()+1)); directory.name = subdir.substr(browsed_dir.size()-1,subdir.size()-browsed_dir.size()+1);
else else
vNameList.push_back(subdir.substr(browsed_dir.size()+1,subdir.size()-browsed_dir.size()-1)); directory.name = subdir.substr(browsed_dir.size()+1,subdir.size()-browsed_dir.size()-1);
vBrowser.push_back(directory);
mBrowser->AddOption("[" + vNameList.back() + "]"); mBrowser->AddOption("[" + directory.name + "]");
if (vNameList.back() == browsed_subdir) if (directory.name == browsed_subdir)
mBrowser->Highlight(mBrowser->MaxChoice()); mBrowser->Highlight(mBrowser->MaxChoice());
break; break;
} }
case MPD_DATA_TYPE_SONG: case MPD_DATA_TYPE_SONG:
{ {
vFileType.push_back(MPD_DATA_TYPE_SONG); BrowsedItem song;
song.type = MPD_DATA_TYPE_SONG;
Song s = browser->song; Song s = browser->song;
vNameList.push_back(s.GetFile()); song.name = s.GetFile();
vHashList.push_back(s.GetHash()); song.hash = s.GetHash();
bool bold = 0; bool bold = 0;
for (vector<Song *>::const_iterator it = vPlaylist.begin(); it != vPlaylist.end(); it++) for (vector<Song *>::const_iterator it = vPlaylist.begin(); it != vPlaylist.end(); it++)
{ {
@@ -566,6 +564,7 @@ void GetDirectory(string dir)
} }
} }
bold ? mBrowser->AddBoldOption(DisplaySong(s)) : mBrowser->AddOption(DisplaySong(s)); bold ? mBrowser->AddBoldOption(DisplaySong(s)) : mBrowser->AddOption(DisplaySong(s));
vBrowser.push_back(song);
break; break;
} }
} }

View File

@@ -27,6 +27,14 @@
#include "settings.h" #include "settings.h"
#include "song.h" #include "song.h"
struct BrowsedItem
{
BrowsedItem() : hash(0) { }
string name;
MpdDataType type;
long long hash;
};
extern ncmpcpp_config Config; extern ncmpcpp_config Config;
bool SortSongsByTrack(const Song &, const Song &); bool SortSongsByTrack(const Song &, const Song &);

View File

@@ -21,6 +21,12 @@
#include "menu.h" #include "menu.h"
#include "misc.h" #include "misc.h"
Menu::~Menu()
{
for (vector<Option *>::iterator it = itsOptions.begin(); it != itsOptions.end(); it++)
delete *it;
}
int Menu::count_length(string str) int Menu::count_length(string str)
{ {
if (str.empty()) if (str.empty())
@@ -60,39 +66,47 @@ int Menu::count_length(string str)
void Menu::AddOption(const string &str, LOCATION location, HAVE_SEPARATOR separator) void Menu::AddOption(const string &str, LOCATION location, HAVE_SEPARATOR separator)
{ {
itsLocations.push_back(location); Option *new_option = new Option;
itsOptions.push_back(str); new_option->content = str;
itsSeparators.push_back(separator); new_option->location = location;
itsStaticOptions.push_back(0); new_option->have_separator = separator;
itsBold.push_back(0); new_option->is_static = 0;
new_option->is_bold = 0;
itsOptions.push_back(new_option);
} }
void Menu::AddBoldOption(const string &str, LOCATION location, HAVE_SEPARATOR separator) void Menu::AddBoldOption(const string &str, LOCATION location, HAVE_SEPARATOR separator)
{ {
itsLocations.push_back(location); Option *new_option = new Option;
itsOptions.push_back(str); new_option->content = str;
itsSeparators.push_back(separator); new_option->location = location;
itsStaticOptions.push_back(0); new_option->have_separator = separator;
itsBold.push_back(1); new_option->is_static = 0;
new_option->is_bold = 1;
itsOptions.push_back(new_option);
} }
void Menu::AddStaticOption(const string &str, LOCATION location, HAVE_SEPARATOR separator) void Menu::AddStaticOption(const string &str, LOCATION location, HAVE_SEPARATOR separator)
{ {
itsLocations.push_back(location); Option *new_option = new Option;
itsOptions.push_back(str); new_option->content = str;
itsSeparators.push_back(separator); new_option->location = location;
itsStaticOptions.push_back(1); new_option->have_separator = separator;
itsBold.push_back(0); new_option->is_static = 1;
new_option->is_bold = 0;
itsOptions.push_back(new_option);
itsStaticsNumber++; itsStaticsNumber++;
} }
void Menu::AddStaticBoldOption(const string &str, LOCATION location, HAVE_SEPARATOR separator) void Menu::AddStaticBoldOption(const string &str, LOCATION location, HAVE_SEPARATOR separator)
{ {
itsLocations.push_back(location); Option *new_option = new Option;
itsOptions.push_back(str); new_option->content = str;
itsSeparators.push_back(separator); new_option->location = location;
itsStaticOptions.push_back(1); new_option->have_separator = separator;
itsBold.push_back(1); new_option->is_static = 1;
new_option->is_bold = 1;
itsOptions.push_back(new_option);
itsStaticsNumber++; itsStaticsNumber++;
} }
@@ -105,9 +119,9 @@ void Menu::UpdateOption(int index, string str, LOCATION location, HAVE_SEPARATOR
{ {
try try
{ {
itsLocations.at(index-1) = location; itsOptions.at(index-1)->location = location;
itsOptions.at(index-1) = str; itsOptions.at(index-1)->content = str;
itsSeparators.at(index-1) = separator; itsOptions.at(index-1)->have_separator = separator;
} }
catch (std::out_of_range) catch (std::out_of_range)
{ {
@@ -118,7 +132,7 @@ void Menu::BoldOption(int index, IS_BOLD bold)
{ {
try try
{ {
itsBold.at(index-1) = bold; itsOptions.at(index-1)->is_bold = bold;
} }
catch (std::out_of_range) catch (std::out_of_range)
{ {
@@ -129,11 +143,11 @@ void Menu::MakeStatic(int index, IS_STATIC stat)
{ {
try try
{ {
if (stat && !itsStaticOptions.at(index-1)) if (stat && !itsOptions.at(index-1)->is_static)
itsStaticsNumber++; itsStaticsNumber++;
if (!stat && itsStaticOptions.at(index-1)) if (!stat && itsOptions.at(index-1)->is_static)
itsStaticsNumber--; itsStaticsNumber--;
itsStaticOptions.at(index-1) = stat; itsOptions.at(index-1)->is_static = stat;
} }
catch (std::out_of_range) catch (std::out_of_range)
{ {
@@ -144,7 +158,7 @@ string Menu::GetCurrentOption() const
{ {
try try
{ {
return itsOptions.at(itsHighlight); return itsOptions.at(itsHighlight)->content;
} }
catch (std::out_of_range) catch (std::out_of_range)
{ {
@@ -156,7 +170,7 @@ string Menu::GetOption(int i) const
{ {
try try
{ {
return itsOptions.at(i-1); return itsOptions.at(i-1)->content;
} }
catch (std::out_of_range) catch (std::out_of_range)
{ {
@@ -168,18 +182,15 @@ void Menu::DeleteOption(int no)
{ {
try try
{ {
if (itsStaticOptions.at(no-1)) if (itsOptions.at(no-1)->is_static)
itsStaticsNumber--; itsStaticsNumber--;
} }
catch (std::out_of_range) catch (std::out_of_range)
{ {
return; return;
} }
itsLocations.erase(itsLocations.begin()+no-1); delete itsOptions[no-1];
itsOptions.erase(itsOptions.begin()+no-1); itsOptions.erase(itsOptions.begin()+no-1);
itsStaticOptions.erase(itsStaticOptions.begin()+no-1);
itsSeparators.erase(itsSeparators.begin()+no-1);
itsBold.erase(itsBold.begin()+no-1);
/*if (itsBeginning > 0 && itsBeginning == itsOptions.size()-itsHeight) /*if (itsBeginning > 0 && itsBeginning == itsOptions.size()-itsHeight)
itsBeginning--; itsBeginning--;
Go(UP);*/ Go(UP);*/
@@ -221,7 +232,7 @@ void Menu::Refresh()
next = 0; next = 0;
try try
{ {
itsSeparators.at(i); itsOptions.at(i);
} }
catch (std::out_of_range) catch (std::out_of_range)
{ {
@@ -239,19 +250,19 @@ void Menu::Refresh()
Reverse(1); Reverse(1);
SetColor(itsHighlightColor); SetColor(itsHighlightColor);
} }
if (itsBold[i]) if (itsOptions[i]->is_bold)
Bold(1); Bold(1);
int ch = itsSeparators[i] ? 0 : 32; int ch = itsOptions[i]->have_separator ? 0 : 32;
mvwhline(itsWindow,line, 0, ch, itsWidth); mvwhline(itsWindow,line, 0, ch, itsWidth);
int strlength = itsLocations[i] != lLeft && BBEnabled ? count_length(itsOptions[i]) : itsOptions[i].length(); int strlength = itsOptions[i]->location != lLeft && BBEnabled ? count_length(itsOptions[i]->content) : itsOptions[i]->content.length();
if (strlength) if (strlength)
{ {
int x = 0; int x = 0;
if (itsLocations[i] == lCenter) if (itsOptions[i]->location == lCenter)
{ {
for (; x < (itsWidth-strlength-(!ch ? 4 : 0))/2; x++); for (; x < (itsWidth-strlength-(!ch ? 4 : 0))/2; x++);
if (!ch) if (!ch)
@@ -262,7 +273,7 @@ void Menu::Refresh()
x += 2; x += 2;
} }
} }
if (itsLocations[i] == lRight) if (itsOptions[i]->location == lRight)
{ {
for (; x < (itsWidth-strlength); x++) for (; x < (itsWidth-strlength); x++)
if (!ch) if (!ch)
@@ -274,9 +285,9 @@ void Menu::Refresh()
} }
} }
WriteXY(x, line, itsOptions[i], 0); WriteXY(x, line, itsOptions[i]->content, 0);
if (!ch && (itsLocations[i] == lCenter || itsLocations[i] == lLeft)) if (!ch && (itsOptions[i]->location == lCenter || itsOptions[i]->location == lLeft))
{ {
x += strlength; x += strlength;
AltCharset(1); AltCharset(1);
@@ -291,7 +302,7 @@ void Menu::Refresh()
Reverse(0); Reverse(0);
SetColor(itsBaseColor); SetColor(itsBaseColor);
} }
if (itsBold[i]) if (itsOptions[i]->is_bold)
Bold(0); Bold(0);
} }
wrefresh(itsWindow); wrefresh(itsWindow);
@@ -409,6 +420,8 @@ void Menu::Highlight(int which)
{ {
if (which <= itsOptions.size()) if (which <= itsOptions.size())
itsHighlight = which-1; itsHighlight = which-1;
else
return;
if (which > itsHeight) if (which > itsHeight)
itsBeginning = itsHighlight-itsHeight/2; itsBeginning = itsHighlight-itsHeight/2;
@@ -424,11 +437,9 @@ void Menu::Reset()
void Menu::Clear(bool clear_screen) void Menu::Clear(bool clear_screen)
{ {
for (vector<Option *>::iterator it = itsOptions.begin(); it != itsOptions.end(); it++)
delete *it;
itsOptions.clear(); itsOptions.clear();
itsStaticOptions.clear();
itsSeparators.clear();
itsLocations.clear();
itsBold.clear();
itsStaticsNumber = 0; itsStaticsNumber = 0;
if (clear_screen) if (clear_screen)
Window::Clear(); Window::Clear();
@@ -437,13 +448,25 @@ void Menu::Clear(bool clear_screen)
int Menu::GetRealChoice() const int Menu::GetRealChoice() const
{ {
int real_choice = 0; int real_choice = 0;
vector<IS_STATIC>::const_iterator it = itsStaticOptions.begin(); vector<Option *>::const_iterator it = itsOptions.begin();
for (int i = 0; i < itsHighlight; it++, i++) for (int i = 0; i < itsHighlight; it++, i++)
if (!*it) real_choice++; if (!(*it)->is_static) real_choice++;
return real_choice+1; return real_choice+1;
} }
bool Menu::IsStatic(int option)
{
try
{
return itsOptions.at(option-1)->is_static;
}
catch (std::out_of_range)
{
return 1;
}
}
Menu Menu::EmptyClone() Menu Menu::EmptyClone()
{ {
return Menu(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder); return Menu(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);

View File

@@ -31,11 +31,20 @@ typedef bool IS_BOLD;
enum LOCATION { lLeft, lCenter, lRight }; enum LOCATION { lLeft, lCenter, lRight };
struct Option
{
string content;
bool is_static;
bool is_bold;
bool have_separator;
LOCATION location;
};
class Menu : public Window class Menu : public Window
{ {
public: public:
Menu(int startx, int starty, int width, int height, string title, COLOR color, BORDER border) : Window(startx, starty, width, height, title, color, border), itsStaticsNumber(0), itsChoice(0), itsBeginning(0), itsHighlight(0), itsHighlightColor(itsBaseColor), itsHighlightEnabled(1) { SetColor(color); } Menu(int startx, int starty, int width, int height, string title, COLOR color, BORDER border) : Window(startx, starty, width, height, title, color, border), itsStaticsNumber(0), itsChoice(0), itsBeginning(0), itsHighlight(0), itsHighlightColor(itsBaseColor), itsHighlightEnabled(1) { SetColor(color); }
virtual ~Menu() {} virtual ~Menu();
virtual void Add(string str) { AddOption(str); } virtual void Add(string str) { AddOption(str); }
void AddOption(const string &, LOCATION = lLeft, HAVE_SEPARATOR = 0); void AddOption(const string &, LOCATION = lLeft, HAVE_SEPARATOR = 0);
@@ -67,19 +76,16 @@ class Menu : public Window
int MaxRealChoice() const { return itsOptions.size()-itsStaticsNumber; } int MaxRealChoice() const { return itsOptions.size()-itsStaticsNumber; }
bool Empty() { return itsOptions.empty(); } bool Empty() { return itsOptions.empty(); }
bool IsStatic(int);
Menu EmptyClone(); Menu EmptyClone();
protected: protected:
vector<string> itsOptions; vector<Option *> itsOptions;
vector<IS_STATIC> itsStaticOptions;
vector<HAVE_SEPARATOR> itsSeparators;
vector<LOCATION> itsLocations;
vector<IS_BOLD> itsBold;
int itsStaticsNumber; int itsStaticsNumber;
int count_length(string); int count_length(string);
bool is_static() { return itsStaticOptions[itsHighlight]; } bool is_static() { return itsOptions[itsHighlight]->is_static; }
int itsChoice; int itsChoice;
int itsBeginning; int itsBeginning;

View File

@@ -59,13 +59,14 @@ ncmpcpp_config Config;
vector<Song *> vPlaylist; vector<Song *> vPlaylist;
vector<Song> vSearched; vector<Song> vSearched;
vector<MpdDataType> vFileType; vector<BrowsedItem> vBrowser;
vector<string> vNameList;
vector<long long> vHashList;
vector<string> vArtists; vector<string> vArtists;
vector<Song> vSongs; vector<Song> vSongs;
vector<int> vFoundPositions;
int found_pos = 0;
Window *wCurrent = 0; Window *wCurrent = 0;
Window *wPrev = 0; Window *wPrev = 0;
Menu *mPlaylist; Menu *mPlaylist;
@@ -212,6 +213,9 @@ int main(int argc, char *argv[])
sHelp->Add("\tZ : Shuffle playlist\n"); sHelp->Add("\tZ : Shuffle playlist\n");
sHelp->Add("\tU u : Start a music database update\n\n"); sHelp->Add("\tU u : Start a music database update\n\n");
sHelp->Add("\t/ : Forward find\n");
sHelp->Add("\t? : Backward find\n");
sHelp->Add("\t. : Go to next/previous found position\n");
sHelp->Add(tag_screen_keydesc); sHelp->Add(tag_screen_keydesc);
sHelp->Add("\tg : Go to chosen position in current song\n\n"); sHelp->Add("\tg : Go to chosen position in current song\n\n");
@@ -228,19 +232,19 @@ int main(int argc, char *argv[])
sHelp->Add("\to : Go to currently playing position\n\n\n"); sHelp->Add("\to : Go to currently playing position\n\n\n");
sHelp->Add(" [b]Keys - Browse screen\n -----------------------------------------[/b]\n"); sHelp->Add(" [b]Keys - Browse screen\n -----------------------------------------[/b]\n");
sHelp->Add("\tEnter : Enter directory/Select and play song\n"); sHelp->Add("\tEnter : Enter directory/Add to playlist and play song\n");
sHelp->Add("\tSpace : Add song to playlist\n"); sHelp->Add("\tSpace : Add song to playlist\n");
sHelp->Add("\tDelete : Delete playlist\n\n"); sHelp->Add("\tDelete : Delete playlist\n\n");
sHelp->Add(" [b]Keys - Search engine\n -----------------------------------------[/b]\n"); sHelp->Add(" [b]Keys - Search engine\n -----------------------------------------[/b]\n");
sHelp->Add("\tEnter : Change option/Select and play song\n"); sHelp->Add("\tEnter : Change option/Add to playlist and play song\n");
sHelp->Add("\tSpace : Add song to playlist\n\n\n"); sHelp->Add("\tSpace : Add song to playlist\n\n\n");
sHelp->Add(" [b]Keys - Media library\n -----------------------------------------[/b]\n"); sHelp->Add(" [b]Keys - Media library\n -----------------------------------------[/b]\n");
sHelp->Add("\tLeft : Previous column\n"); sHelp->Add("\tLeft : Previous column\n");
sHelp->Add("\tRight : Next column\n"); sHelp->Add("\tRight : Next column\n");
sHelp->Add("\tEnter : Select and play song/album/artist's songs\n"); sHelp->Add("\tEnter : Add to playlist and play song/album/artist's songs\n");
sHelp->Add("\tSpace : Select song/album/artist's songs\n\n\n"); sHelp->Add("\tSpace : Add to playlist song/album/artist's songs\n\n\n");
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
sHelp->Add(" [b]Keys - Tag editor\n -----------------------------------------[/b]\n"); sHelp->Add(" [b]Keys - Tag editor\n -----------------------------------------[/b]\n");
@@ -555,10 +559,12 @@ int main(int argc, char *argv[])
case csBrowser: case csBrowser:
{ {
int ci = mBrowser->GetChoice()-1; int ci = mBrowser->GetChoice()-1;
switch (vFileType[ci]) switch (vBrowser[ci].type)
{ {
case MPD_DATA_TYPE_DIRECTORY: case MPD_DATA_TYPE_DIRECTORY:
{ {
found_pos = 0;
vFoundPositions.clear();
if (browsed_dir != "/" && ci == 0) if (browsed_dir != "/" && ci == 0)
{ {
int i = browsed_dir.size(); int i = browsed_dir.size();
@@ -577,14 +583,14 @@ int main(int argc, char *argv[])
} }
else else
if (browsed_dir != "/") if (browsed_dir != "/")
GetDirectory(browsed_dir + "/" + vNameList[ci]); GetDirectory(browsed_dir + "/" + vBrowser[ci].name);
else else
GetDirectory(vNameList[ci]); GetDirectory(vBrowser[ci].name);
break; break;
} }
case MPD_DATA_TYPE_SONG: case MPD_DATA_TYPE_SONG:
{ {
string &file = vNameList[ci]; string &file = vBrowser[ci].name;
mpd_Song *test = mpd_database_get_fileinfo(conn, (char *) file.c_str()); mpd_Song *test = mpd_database_get_fileinfo(conn, (char *) file.c_str());
if (test) if (test)
{ {
@@ -601,8 +607,8 @@ int main(int argc, char *argv[])
case MPD_DATA_TYPE_PLAYLIST: case MPD_DATA_TYPE_PLAYLIST:
{ {
int howmany = 0; int howmany = 0;
ShowMessage("Loading and playing playlist " + vNameList[ci] + "..."); ShowMessage("Loading and playing playlist " + vBrowser[ci].name + "...");
MpdData *list = mpd_database_get_playlist_content(conn, (char *) vNameList[ci].c_str()); MpdData *list = mpd_database_get_playlist_content(conn, (char *) vBrowser[ci].name.c_str());
Song tmp; Song tmp;
if (list) if (list)
tmp = list->song; tmp = list->song;
@@ -642,7 +648,7 @@ int main(int argc, char *argv[])
{ {
case 1: case 1:
{ {
wFooter->WriteXY(0, 1, "[b]New title:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]New title:[/b] ", 1);
if (s.GetTitle() == UNKNOWN_TITLE) if (s.GetTitle() == UNKNOWN_TITLE)
s.SetTitle(wFooter->GetString("", TraceMpdStatus)); s.SetTitle(wFooter->GetString("", TraceMpdStatus));
else else
@@ -652,7 +658,7 @@ int main(int argc, char *argv[])
} }
case 2: case 2:
{ {
wFooter->WriteXY(0, 1, "[b]New artist:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]New artist:[/b] ", 1);
if (s.GetArtist() == UNKNOWN_ARTIST) if (s.GetArtist() == UNKNOWN_ARTIST)
s.SetArtist(wFooter->GetString("", TraceMpdStatus)); s.SetArtist(wFooter->GetString("", TraceMpdStatus));
else else
@@ -662,7 +668,7 @@ int main(int argc, char *argv[])
} }
case 3: case 3:
{ {
wFooter->WriteXY(0, 1, "[b]New album:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]New album:[/b] ", 1);
if (s.GetAlbum() == UNKNOWN_ALBUM) if (s.GetAlbum() == UNKNOWN_ALBUM)
s.SetAlbum(wFooter->GetString("", TraceMpdStatus)); s.SetAlbum(wFooter->GetString("", TraceMpdStatus));
else else
@@ -672,7 +678,7 @@ int main(int argc, char *argv[])
} }
case 4: case 4:
{ {
wFooter->WriteXY(0, 1, "[b]New year:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]New year:[/b] ", 1);
if (s.GetYear() == EMPTY_TAG) if (s.GetYear() == EMPTY_TAG)
s.SetYear(wFooter->GetString(4, TraceMpdStatus)); s.SetYear(wFooter->GetString(4, TraceMpdStatus));
else else
@@ -682,7 +688,7 @@ int main(int argc, char *argv[])
} }
case 5: case 5:
{ {
wFooter->WriteXY(0, 1, "[b]New track:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]New track:[/b] ", 1);
if (s.GetTrack() == EMPTY_TAG) if (s.GetTrack() == EMPTY_TAG)
s.SetTrack(wFooter->GetString(3, TraceMpdStatus)); s.SetTrack(wFooter->GetString(3, TraceMpdStatus));
else else
@@ -692,7 +698,7 @@ int main(int argc, char *argv[])
} }
case 6: case 6:
{ {
wFooter->WriteXY(0, 1, "[b]New genre:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]New genre:[/b] ", 1);
if (s.GetGenre() == EMPTY_TAG) if (s.GetGenre() == EMPTY_TAG)
s.SetGenre(wFooter->GetString("", TraceMpdStatus)); s.SetGenre(wFooter->GetString("", TraceMpdStatus));
else else
@@ -702,7 +708,7 @@ int main(int argc, char *argv[])
} }
case 7: case 7:
{ {
wFooter->WriteXY(0, 1, "[b]New comment:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]New comment:[/b] ", 1);
if (s.GetComment() == EMPTY_TAG) if (s.GetComment() == EMPTY_TAG)
s.SetComment(wFooter->GetString("", TraceMpdStatus)); s.SetComment(wFooter->GetString("", TraceMpdStatus));
else else
@@ -745,9 +751,18 @@ int main(int argc, char *argv[])
current_screen = prev_screen; current_screen = prev_screen;
if (current_screen == csLibrary) if (current_screen == csLibrary)
{ {
mLibSongs->HighlightColor(Config.main_color); # ifdef HAVE_TAGLIB_H
mLibArtists->HighlightColor(Config.library_active_column_color); if (id == 8)
wCurrent = mLibArtists; {
mLibSongs->HighlightColor(Config.main_color);
mLibArtists->HighlightColor(Config.library_active_column_color);
wCurrent = mLibArtists;
}
else
wCurrent = wPrev;
# else
wCurrent = wPrev;
# endif
mLibArtists->Display(); mLibArtists->Display();
mvvline(main_start_y, lib_albums_start_x-1, 0, main_height); mvvline(main_start_y, lib_albums_start_x-1, 0, main_height);
mLibAlbums->Display(); mLibAlbums->Display();
@@ -773,7 +788,7 @@ int main(int argc, char *argv[])
{ {
case 1: case 1:
{ {
wFooter->WriteXY(0, 1, "[b]Filename:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]Filename:[/b] ", 1);
if (s.GetShortFilename() == EMPTY_TAG) if (s.GetShortFilename() == EMPTY_TAG)
s.SetShortFilename(wFooter->GetString("", TraceMpdStatus)); s.SetShortFilename(wFooter->GetString("", TraceMpdStatus));
else else
@@ -783,7 +798,7 @@ int main(int argc, char *argv[])
} }
case 2: case 2:
{ {
wFooter->WriteXY(0, 1, "[b]Title:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]Title:[/b] ", 1);
if (s.GetTitle() == UNKNOWN_TITLE) if (s.GetTitle() == UNKNOWN_TITLE)
s.SetTitle(wFooter->GetString("", TraceMpdStatus)); s.SetTitle(wFooter->GetString("", TraceMpdStatus));
else else
@@ -793,7 +808,7 @@ int main(int argc, char *argv[])
} }
case 3: case 3:
{ {
wFooter->WriteXY(0, 1, "[b]Artist:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]Artist:[/b] ", 1);
if (s.GetArtist() == UNKNOWN_ARTIST) if (s.GetArtist() == UNKNOWN_ARTIST)
s.SetArtist(wFooter->GetString("", TraceMpdStatus)); s.SetArtist(wFooter->GetString("", TraceMpdStatus));
else else
@@ -803,7 +818,7 @@ int main(int argc, char *argv[])
} }
case 4: case 4:
{ {
wFooter->WriteXY(0, 1, "[b]Album:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]Album:[/b] ", 1);
if (s.GetAlbum() == UNKNOWN_ALBUM) if (s.GetAlbum() == UNKNOWN_ALBUM)
s.SetAlbum(wFooter->GetString("", TraceMpdStatus)); s.SetAlbum(wFooter->GetString("", TraceMpdStatus));
else else
@@ -813,7 +828,7 @@ int main(int argc, char *argv[])
} }
case 5: case 5:
{ {
wFooter->WriteXY(0, 1, "[b]Year:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]Year:[/b] ", 1);
if (s.GetYear() == EMPTY_TAG) if (s.GetYear() == EMPTY_TAG)
s.SetYear(wFooter->GetString(4, TraceMpdStatus)); s.SetYear(wFooter->GetString(4, TraceMpdStatus));
else else
@@ -823,7 +838,7 @@ int main(int argc, char *argv[])
} }
case 6: case 6:
{ {
wFooter->WriteXY(0, 1, "[b]Track:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]Track:[/b] ", 1);
if (s.GetTrack() == EMPTY_TAG) if (s.GetTrack() == EMPTY_TAG)
s.SetTrack(wFooter->GetString(3, TraceMpdStatus)); s.SetTrack(wFooter->GetString(3, TraceMpdStatus));
else else
@@ -833,7 +848,7 @@ int main(int argc, char *argv[])
} }
case 7: case 7:
{ {
wFooter->WriteXY(0, 1, "[b]Genre:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]Genre:[/b] ", 1);
if (s.GetGenre() == EMPTY_TAG) if (s.GetGenre() == EMPTY_TAG)
s.SetGenre(wFooter->GetString("", TraceMpdStatus)); s.SetGenre(wFooter->GetString("", TraceMpdStatus));
else else
@@ -843,7 +858,7 @@ int main(int argc, char *argv[])
} }
case 8: case 8:
{ {
wFooter->WriteXY(0, 1, "[b]Comment:[/b] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "[b]Comment:[/b] ", 1);
if (s.GetComment() == EMPTY_TAG) if (s.GetComment() == EMPTY_TAG)
s.SetComment(wFooter->GetString("", TraceMpdStatus)); s.SetComment(wFooter->GetString("", TraceMpdStatus));
else else
@@ -900,6 +915,8 @@ int main(int argc, char *argv[])
} }
case 14: case 14:
{ {
found_pos = 0;
vFoundPositions.clear();
vSearched.clear(); vSearched.clear();
PrepareSearchEngine(searched_song); PrepareSearchEngine(searched_song);
ShowMessage("Search state reset"); ShowMessage("Search state reset");
@@ -1012,11 +1029,11 @@ int main(int argc, char *argv[])
if (current_screen == csBrowser) if (current_screen == csBrowser)
{ {
int ci = mBrowser->GetChoice()-1; int ci = mBrowser->GetChoice()-1;
switch (vFileType[ci]) switch (vBrowser[ci].type)
{ {
case MPD_DATA_TYPE_DIRECTORY: case MPD_DATA_TYPE_DIRECTORY:
{ {
string getdir = browsed_dir == "/" ? vNameList[ci] : browsed_dir + "/" + vNameList[ci]; string getdir = browsed_dir == "/" ? vBrowser[ci].name : browsed_dir + "/" + vBrowser[ci].name;
MpdData *queue = mpd_database_get_directory_recursive(conn, (char *) getdir.c_str()); MpdData *queue = mpd_database_get_directory_recursive(conn, (char *) getdir.c_str());
FOR_EACH_MPD_DATA(queue) FOR_EACH_MPD_DATA(queue)
@@ -1028,10 +1045,10 @@ int main(int argc, char *argv[])
} }
case MPD_DATA_TYPE_SONG: case MPD_DATA_TYPE_SONG:
{ {
mpd_Song *test = mpd_database_get_fileinfo(conn, (char *) vNameList[ci].c_str()); mpd_Song *test = mpd_database_get_fileinfo(conn, (char *) vBrowser[ci].name.c_str());
if (test) if (test)
{ {
mpd_playlist_queue_add(conn, (char *) vNameList[ci].c_str()); mpd_playlist_queue_add(conn, (char *) vBrowser[ci].name.c_str());
Song s = test; Song s = test;
ShowMessage("Added to playlist: " + OmitBBCodes(DisplaySong(s))); ShowMessage("Added to playlist: " + OmitBBCodes(DisplaySong(s)));
mpd_playlist_queue_commit(conn); mpd_playlist_queue_commit(conn);
@@ -1041,8 +1058,8 @@ int main(int argc, char *argv[])
} }
case MPD_DATA_TYPE_PLAYLIST: case MPD_DATA_TYPE_PLAYLIST:
{ {
ShowMessage("Loading playlist " + vNameList[ci] + "..."); ShowMessage("Loading playlist " + vBrowser[ci].name + "...");
MpdData *list = mpd_database_get_playlist_content(conn, (char *) vNameList[ci].c_str()); MpdData *list = mpd_database_get_playlist_content(conn, (char *) vBrowser[ci].name.c_str());
FOR_EACH_MPD_DATA(list) FOR_EACH_MPD_DATA(list)
mpd_playlist_queue_add(conn, list->song->file); mpd_playlist_queue_add(conn, list->song->file);
mpd_data_free(list); mpd_data_free(list);
@@ -1161,10 +1178,10 @@ int main(int argc, char *argv[])
{ {
BLOCK_STATUSBAR_UPDATE; BLOCK_STATUSBAR_UPDATE;
int id = mBrowser->GetChoice()-1; int id = mBrowser->GetChoice()-1;
if (vFileType[id] == MPD_DATA_TYPE_PLAYLIST) if (vBrowser[id].type == MPD_DATA_TYPE_PLAYLIST)
{ {
block_statusbar_update = 1; block_statusbar_update = 1;
wFooter->WriteXY(0, 1, "Delete playlist " + vNameList[id] + " ? [y/n] ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "Delete playlist " + vBrowser[id].name + " ? [y/n] ", 1);
curs_set(1); curs_set(1);
int in = 0; int in = 0;
do do
@@ -1176,8 +1193,8 @@ int main(int argc, char *argv[])
block_statusbar_update = 0; block_statusbar_update = 0;
if (in == 'y') if (in == 'y')
{ {
mpd_database_delete_playlist(conn, (char *) vNameList[id].c_str()); mpd_database_delete_playlist(conn, (char *) vBrowser[id].name.c_str());
ShowMessage("Playlist " + vNameList[id] + " deleted!"); ShowMessage("Playlist " + vBrowser[id].name + " deleted!");
GetDirectory("/"); GetDirectory("/");
} }
else else
@@ -1207,7 +1224,7 @@ int main(int argc, char *argv[])
{ {
string playlist_name; string playlist_name;
BLOCK_STATUSBAR_UPDATE; BLOCK_STATUSBAR_UPDATE;
wFooter->WriteXY(0, 1, "Save playlist as: ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "Save playlist as: ", 1);
playlist_name = wFooter->GetString("", TraceMpdStatus); playlist_name = wFooter->GetString("", TraceMpdStatus);
UNBLOCK_STATUSBAR_UPDATE; UNBLOCK_STATUSBAR_UPDATE;
if (playlist_name.find("/") != string::npos) if (playlist_name.find("/") != string::npos)
@@ -1227,7 +1244,7 @@ int main(int argc, char *argv[])
break; break;
} }
} }
if (browsed_dir == "/" && !vNameList.empty()) if (browsed_dir == "/" && !vBrowser.empty())
GetDirectory(browsed_dir); GetDirectory(browsed_dir);
break; break;
} }
@@ -1397,9 +1414,9 @@ int main(int argc, char *argv[])
} }
case csBrowser: case csBrowser:
{ {
if (vFileType[id] == MPD_DATA_TYPE_SONG) if (vBrowser[id].type == MPD_DATA_TYPE_SONG)
{ {
Song edited = mpd_database_get_fileinfo(conn, vNameList[id].c_str()); Song edited = mpd_database_get_fileinfo(conn, vBrowser[id].name.c_str());
if (GetSongInfo(edited)) if (GetSongInfo(edited))
{ {
wCurrent = mTagEditor; wCurrent = mTagEditor;
@@ -1455,7 +1472,7 @@ int main(int argc, char *argv[])
int newpos = 0; int newpos = 0;
string position; string position;
BLOCK_STATUSBAR_UPDATE; BLOCK_STATUSBAR_UPDATE;
wFooter->WriteXY(0, 1, "Position to go (in %): ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "Position to go (in %): ", 1);
position = wFooter->GetString(3, TraceMpdStatus); position = wFooter->GetString(3, TraceMpdStatus);
newpos = atoi(position.c_str()); newpos = atoi(position.c_str());
if (newpos > 0 && newpos < 100 && !position.empty()) if (newpos > 0 && newpos < 100 && !position.empty())
@@ -1486,6 +1503,68 @@ int main(int argc, char *argv[])
ShowMessage("Cleared playlist!"); ShowMessage("Cleared playlist!");
break; break;
} }
case '/': case '?': // find forward/backward
{
if (current_screen != csHelp && current_screen != csSearcher || (current_screen == csSearcher && !vSearched.empty()))
{
string how = input == '/' ? "forward" : "backward";
found_pos = 0;
vFoundPositions.clear();
Menu *mCurrent = static_cast<Menu *>(wCurrent);
BLOCK_STATUSBAR_UPDATE;
wFooter->WriteXY(0, Config.statusbar_visibility, "Find " + how + ": ", 1);
string findme = wFooter->GetString("", TraceMpdStatus);
UNBLOCK_STATUSBAR_UPDATE;
timer = time(NULL);
if (findme.empty())
break;
transform(findme.begin(), findme.end(), findme.end(), tolower);
if (input == '/') // forward
{
for (int i = mCurrent->GetChoice(); i <= mCurrent->MaxChoice(); i++)
{
string name = mCurrent->GetOption(i);
transform(name.begin(), name.end(), name.begin(), tolower);
if (name.find(findme) != string::npos && !mCurrent->IsStatic(i))
vFoundPositions.push_back(i);
}
}
else // backward
{
for (int i = mCurrent->GetChoice(); i > 0; i--)
{
string name = mCurrent->GetOption(i);
transform(name.begin(), name.end(), name.begin(), tolower);
if (name.find(findme) != string::npos && !mCurrent->IsStatic(i))
vFoundPositions.push_back(i);
}
}
if (vFoundPositions.empty())
ShowMessage("Unable to find \"" + findme + "\"");
else
mCurrent->Highlight(vFoundPositions.front());
}
break;
}
case '.': // go to next/previous found position
{
if (!vFoundPositions.empty())
{
Menu *mCurrent = static_cast<Menu *>(wCurrent);
try
{
mCurrent->Highlight(vFoundPositions.at(++found_pos));
}
catch (std::out_of_range)
{
mCurrent->Highlight(vFoundPositions.front());
found_pos = 0;
}
}
break;
}
case '1': // help screen case '1': // help screen
{ {
if (wCurrent != sHelp) if (wCurrent != sHelp)
@@ -1500,6 +1579,8 @@ int main(int argc, char *argv[])
{ {
if (wCurrent != mPlaylist && current_screen != csTagEditor) if (wCurrent != mPlaylist && current_screen != csTagEditor)
{ {
found_pos = 0;
vFoundPositions.clear();
wCurrent = mPlaylist; wCurrent = mPlaylist;
wCurrent->Hide(); wCurrent->Hide();
current_screen = csPlaylist; current_screen = csPlaylist;
@@ -1516,13 +1597,13 @@ int main(int argc, char *argv[])
else else
{ {
bool bold = 0; bool bold = 0;
for (int i = 0; i < vFileType.size(); i++) for (int i = 0; i < vBrowser.size(); i++)
{ {
if (vFileType[i] == MPD_DATA_TYPE_SONG) if (vBrowser[i].type == MPD_DATA_TYPE_SONG)
{ {
for (vector<Song *>::const_iterator it = vPlaylist.begin(); it != vPlaylist.end(); it++) for (vector<Song *>::const_iterator it = vPlaylist.begin(); it != vPlaylist.end(); it++)
{ {
if ((*it)->GetHash() == vHashList[i]) if ((*it)->GetHash() == vBrowser[i].hash)
{ {
bold = 1; bold = 1;
break; break;
@@ -1535,6 +1616,8 @@ int main(int argc, char *argv[])
} }
if (wCurrent != mBrowser && current_screen != csTagEditor) if (wCurrent != mBrowser && current_screen != csTagEditor)
{ {
found_pos = 0;
vFoundPositions.clear();
wCurrent = mBrowser; wCurrent = mBrowser;
wCurrent->Hide(); wCurrent->Hide();
current_screen = csBrowser; current_screen = csBrowser;
@@ -1545,6 +1628,8 @@ int main(int argc, char *argv[])
{ {
if (current_screen != csTagEditor && current_screen != csSearcher) if (current_screen != csTagEditor && current_screen != csSearcher)
{ {
found_pos = 0;
vFoundPositions.clear();
if (vSearched.empty()) if (vSearched.empty())
PrepareSearchEngine(searched_song); PrepareSearchEngine(searched_song);
wCurrent = mSearcher; wCurrent = mSearcher;
@@ -1576,6 +1661,9 @@ int main(int argc, char *argv[])
{ {
if (current_screen != csLibrary) if (current_screen != csLibrary)
{ {
found_pos = 0;
vFoundPositions.clear();
if (mLibArtists->Empty()) if (mLibArtists->Empty())
{ {
MpdData *data = mpd_database_get_artists(conn); MpdData *data = mpd_database_get_artists(conn);

View File

@@ -68,8 +68,8 @@ class Song
void SetArtist(string str) { itsArtist = str; } void SetArtist(string str) { itsArtist = str; }
void SetTitle(string str) { itsTitle = str; } void SetTitle(string str) { itsTitle = str; }
void SetAlbum(string str) { itsAlbum = str; } void SetAlbum(string str) { itsAlbum = str; }
void SetTrack(string str) { itsTrack = IntoStr(StrToInt(str)); } void SetTrack(string str) { itsTrack = str.empty() ? "" : IntoStr(StrToInt(str)); }
void SetYear(string str) { itsYear = IntoStr(StrToInt(str)); } void SetYear(string str) { itsYear = str.empty() ? "" : IntoStr(StrToInt(str)); }
void SetGenre(string str) { itsGenre = str; } void SetGenre(string str) { itsGenre = str; }
void SetComment(string str) { itsComment = str; } void SetComment(string str) { itsComment = str; }
void SetPosition(int pos) { itsPosition = pos; } void SetPosition(int pos) { itsPosition = pos; }

View File

@@ -41,9 +41,7 @@ extern Window *wFooter;
extern vector<Song *> vPlaylist; extern vector<Song *> vPlaylist;
extern vector<Song> vSearched; extern vector<Song> vSearched;
extern vector<MpdDataType> vFileType; extern vector<BrowsedItem> vBrowser;
extern vector<string> vNameList;
extern vector<long long> vHashList;
extern time_t block_delay; extern time_t block_delay;
extern time_t timer; extern time_t timer;
@@ -213,13 +211,13 @@ void NcmpcppStatusChanged(MpdObj *conn, ChangedStatusType what)
if (current_screen == csBrowser) if (current_screen == csBrowser)
{ {
bool bold = 0; bool bold = 0;
for (int i = 0; i < vFileType.size(); i++) for (int i = 0; i < vBrowser.size(); i++)
{ {
if (vFileType[i] == MPD_DATA_TYPE_SONG) if (vBrowser[i].type == MPD_DATA_TYPE_SONG)
{ {
for (vector<Song *>::const_iterator it = vPlaylist.begin(); it != vPlaylist.end(); it++) for (vector<Song *>::const_iterator it = vPlaylist.begin(); it != vPlaylist.end(); it++)
{ {
if ((*it)->GetHash() == vHashList[i]) if ((*it)->GetHash() == vBrowser[i].hash)
{ {
bold = 1; bold = 1;
break; break;